Compare commits

..

746 Commits

Author SHA1 Message Date
John Bintz 5e4ffeae9f ensure query strings are built correctly for mechanize 2010-06-01 14:29:57 -04:00
John Bintz 0856d8d405 potential fix for invalid query string construction 2010-06-01 14:10:39 -04:00
Bryan Helmkamp 8f637e6785 Bumping version to prerelease until next release 2010-04-26 22:15:41 -04:00
Bryan Helmkamp 312c175384 Releasing v0.7.1 2010-04-26 22:10:16 -04:00
Damian Janowski 7cde0573c0 Update changelog. 2010-04-23 13:19:45 -03:00
Luismi Cavalle 43b19eeafa Fix have_xpath not matching negative expectation in the block.
[#182 state:resolved]
2010-04-23 13:17:49 -03:00
Damian Janowski 107bdf7cf9 Update Gemfile to the newest Bundler. 2010-04-23 13:15:30 -03:00
Damian Janowski 71a281066e Update changelog. 2010-04-23 13:09:05 -03:00
Damian Janowski 438e53c295 Fix broken integration test in 1.9.1-p378. 2010-04-22 19:09:45 -03:00
Noah Davis 80ea640901 Fix selenium webrat tests in FF/Safari -- locatedLabel.htmlFor returns empty string in FF/Safari which breaks location strategy for label 2010-04-20 23:46:43 -04:00
Noah Davis 68d5fde17a Move verbose selenium output that can clutter build output behind setting 2010-04-20 11:44:55 -04:00
Damian Janowski 1979a7fc7f Use `htmlFor` on IE.
[#317 state:resolved]
2010-04-15 15:40:03 -03:00
Álvaro Gil 06bb72d24f fix post method in mechanize adapter to handle data as array or hash
it fixes spec/integration/mechanize/sample_app.rb:20
2010-04-13 15:40:24 -03:00
Damian Janowski c49123c772 Fix Mechanize spec. 2010-04-13 13:25:28 -03:00
Damian Janowski 2c9de38129 Add missing spec that shows a regression after e3bcf5. 2010-04-13 12:57:25 -03:00
Damian Janowski 2a6c67b17b Fix delegation of `response_headers` method.
[#332 state:resolved]
2010-04-13 12:04:36 -03:00
Damian Janowski 38e699820f Merge remote branch 'wemrysi/master' into mechanize_redirects
Conflicts:
	lib/webrat/adapters/mechanize.rb
2010-04-13 12:01:22 -03:00
Damian Janowski 4c62279fc1 The WWW namespace is deprecated as of Mechanize 1.0.
[#368 state:resolved]
2010-04-12 23:38:04 -03:00
Damian Janowski deccefa2c3 Some explicit requires of RubyGems are necessary for integration tests.
Should not affect the way Webrat behaves as a library.
2010-04-12 23:30:56 -03:00
Simon Rozet 10c70a37de Get rid of needless require "rubygems" 2010-04-12 22:28:14 -03:00
Damian Janowski 19fc2ccb89 Remove warnings [#372 state:resolved].
On why this is important:
http://eigenclass.org/hiki/ruby-warnings-SEX-and-stds
2010-04-12 22:25:53 -03:00
Larry Marburger fd944cccb5 Webrat::Core::Session#redirect? should not mistake a 304 for a redirect. 2010-04-12 17:52:09 -03:00
Damian Janowski 0bbf163d4f Better stack traces when using class_eval (Alex Chaffee). 2010-04-12 17:45:10 -03:00
Damian Janowski ef6874c855 Allow submitting forms by CSS selectors too.
Priority is given to selecting by ID for backwards compatibility.

Also add pending `submit_form` specs.
2010-04-12 17:35:12 -03:00
Damian Janowski e3bcf5c599 Merge branch 'nested_params_support' 2010-04-12 17:22:54 -03:00
Damian Janowski bd6cd436de Point users in the right direction when selenium is not available. 2010-04-12 16:39:27 -03:00
Álvaro Gil e36487458f test added for nested params files upload 2010-04-09 11:38:33 -03:00
Álvaro Gil c49e23d81d fixes #341 attach_file with nested attributes 2010-04-05 11:31:38 -03:00
Álvaro Gil 15102bd60d !trivial: define and call class methods in From appropriate 2010-04-05 11:07:35 -03:00
Álvaro Gil fa881a88c8 build querystring with all form elements and then parse to get query params
* Basically Field#to_param was replaced for Field#to_query_string and
some methods related to build params were moved to Form class.

Before this commit the params hash was made by parsing each element
querystring to param and then merge, now we build the whole querystring
first and then parse it to get params with Rack or Rails depending of
the configure mode.
2010-04-03 12:07:16 -03:00
Noah Davis 2f12422ae8 New webrat configuration option selenium_firefox_profile which is passed to selenium server 2010-02-26 15:54:31 -05:00
Emrys Ingersoll 67febe9072 Normalize access to response headers in adapters 2010-02-20 17:06:30 -05:00
Emrys Ingersoll 56b2f342da Adding spec for disabling automatic redirects in Mechanize 2010-02-18 19:04:11 -05:00
Emrys Ingersoll b2dddf2f09 Disable the automatic following of redirects in the Mechanize instance so they can be handled by Webrat::Session 2010-02-18 18:33:22 -05:00
lukemelia d9d9cc1fcc Added application_port_for_selenium to webrat configuration. The use case is when you want to test through a web server sitting in front of your application server. 2010-01-18 09:49:44 -05:00
Noah Davis 0387d9eacc Bumping version to prerelease until next official release 2010-01-17 20:48:23 -05:00
Noah Davis d73eca71ee Releasing v 0.7.0 2010-01-17 20:44:20 -05:00
Noah Davis 8d2fa24b4a Added missing dependency "rack-test" to gemspec (LH #339) 2010-01-17 20:42:37 -05:00
Bryan Helmkamp eb3a4ff5d6 Whitespace 2010-01-17 20:35:42 -05:00
hpoydar 4ac8456a48 Replaced selenium standalone jar to fix Snow Leopard + Firefox 3.5 issue 2010-01-17 20:30:55 -05:00
Noah Davis 3159ae081f changelog update 2010-01-17 20:23:48 -05:00
Noah Davis ccaf41160c Save and open page storage directory now defaults to "tmp" under current directory if exists, otherwise current directory 2010-01-17 18:29:35 -05:00
Noah Davis d50d24e09e Documentation fix for application environment 2010-01-17 18:08:40 -05:00
Noah Davis 1874f6d395 Removed save_and_open_page's rewriting of static asset paths before saving (was not actually working) 2010-01-16 19:28:29 -05:00
Noah Davis 71dcfb327d Save and open page directory specified via configuration 2010-01-16 19:18:28 -05:00
Noah Davis db168bedec Make "should contain" ignore extra whitespace when doing string comparisons 2010-01-13 16:47:35 -05:00
lukemelia f9985cd488 Make selenium matchers handle negative match more consistently with positive match 2010-01-05 18:33:45 -05:00
Bryan Helmkamp b64d68a2a8 Bump VERSION to prerelease 2009-11-28 00:24:47 -05:00
Bryan Helmkamp 4081fe5538 Prep for 0.6.0 release 2009-11-28 00:18:58 -05:00
Bryan Helmkamp 3bd7266ab9 Merge branch 'lh_292'
Conflicts:
	History.txt
2009-11-15 16:51:23 -05:00
Bryan Helmkamp a9ff3efcd7 History 2009-11-15 16:50:46 -05:00
Michael Klett 61b0fce828 Base64 encoding of HTTP basic auth credentials should omit newlines (do not enforce a 76 character line limit)
According to RFC 2617 (http://www.ietf.org/rfc/rfc2617.txt), the 76 character line limit normally enforced by Base64 encoding should not apply to the encoding of HTTP basic authentication credentials.
2009-11-15 16:50:40 -05:00
Bryan Helmkamp f9f2a98189 History 2009-11-15 16:50:39 -05:00
David Chelimsky 51bdded2ce require 'nokogiri' in rspec-rails include file 2009-11-15 16:50:39 -05:00
Bryan Helmkamp 4de7d64776 History 2009-11-15 16:42:39 -05:00
Bryan Helmkamp 13d513837a Merge remote branch 'dchelimsky/require_nokogiri' into lh_293 2009-11-15 16:41:37 -05:00
Bryan Helmkamp ba95363486 Spec fix: Don't depend on Nokogiri #inspect output 2009-11-15 16:38:09 -05:00
Bryan Helmkamp 672bd583af Whitespace 2009-11-15 16:29:44 -05:00
Bryan Helmkamp 0536360773 History 2009-11-15 16:29:27 -05:00
Jonathan Weiss ea4a52ccf1 add support for Rails 2.3.4 form authenticity tokens 2009-11-15 16:24:56 -05:00
Bryan Helmkamp cbb07306d4 Regenerate gemspec with thor tasks 2009-11-15 16:07:38 -05:00
Bryan Helmkamp 5a05d860ec Use simple Thor tasks for release management instead of Jeweler 2009-11-15 15:49:38 -05:00
Bryan Helmkamp 05af4dd2a0 Switching to Safari until Snow Leopard + Firefox + Selenium is fixed
http://jira.openqa.org/browse/SRC-743
2009-11-13 21:23:27 -05:00
Bryan Helmkamp 7812f25741 Don't blow up if PID doesn't exist at the end 2009-11-13 21:22:41 -05:00
Bryan Helmkamp fcde80f43f Avoid Selenium test bleed by ending with an assertion about the next page 2009-11-13 21:17:41 -05:00
Bryan Helmkamp 1ce72b6912 Ending selenium tests with assertions avoids "test bleed" 2009-11-13 21:10:25 -05:00
Bryan Helmkamp bb282d992e Remove a couple more bogus tests
<input type="button" /> doesn't submit forms
2009-11-13 21:07:21 -05:00
Bryan Helmkamp f6dd24f7c5 Remove bogus integration tests that were passing (sometimes) by coincidence
An element of <button type="button" /> is not supposed to submit a form
2009-11-13 20:57:55 -05:00
Bryan Helmkamp d0cadf8a76 Update file location for Rails 2.3.4 2009-11-13 20:52:14 -05:00
Bryan Helmkamp 1c28425583 Use Bundler for managing dependencies needed to run the tests 2009-11-13 17:41:33 -05:00
David Chelimsky 9a92afedff require 'nokogiri' in rspec-rails include file 2009-09-23 23:04:43 -05:00
Bryan Helmkamp f51b745e89 When a timeout occurs in wait_for, include the HTML from Selenium in the exception 2009-09-22 15:23:49 -04:00
Bryan Helmkamp 8dacd973aa Regenerated gemspec for version 0.6.rc1 2009-09-22 12:44:56 -04:00
Bryan Helmkamp 194d3250cc Prep for 0.6.rc1 release 2009-09-22 12:41:57 -04:00
Bryan Helmkamp b68c6859e8 History 2009-09-22 12:41:41 -04:00
Bryan Helmkamp 87c54dde2e Fix typo in Rakefile 2009-09-19 17:57:35 -04:00
Bryan Helmkamp 042b416092 Whitespace 2009-09-19 17:34:09 -04:00
Bryan Helmkamp 40d7f970e0 Gracefully handle cases where RSpec is not installed in Rakefile 2009-09-19 17:32:42 -04:00
Bryan Helmkamp 03f2023117 Make link location in Selenium more reliable and consistent with non-Selenium 2009-09-18 15:49:06 -04:00
Bryan Helmkamp b51ba029db Fix support for passing in an ActiveRecord model to within (which uses dom_id) LB/BH 2009-09-18 11:28:07 -04:00
Bryan Helmkamp 862471476f Run Selenium tests during spec:integration 2009-09-17 22:13:10 -04:00
Bryan Helmkamp c689166c48 Fix "element.getAttribute is not a function" Selenium errors when filling in fields
The root cause was the locator strategy was naively returning an element that was not a form field, causing Selenium's internals to blow up
2009-09-17 21:32:56 -04:00
Bryan Helmkamp 3a9e7d3999 Fix bugs when dealing with special characters in labels 2009-09-17 21:18:52 -04:00
Bryan Helmkamp 63e1053afa Fix bug in Selenium when dealing with special characters in link text 2009-09-17 20:28:19 -04:00
Bryan Helmkamp aae82b5111 Whitespace 2009-09-17 20:15:40 -04:00
Bryan Helmkamp e7a3ac865c Guard tests for things that aren't supported in Selenium yet 2009-09-17 20:13:04 -04:00
Bryan Helmkamp 8772505322 History 2009-09-07 14:16:23 -04:00
Bryan Helmkamp b0ef59f5ec Properly handle multiline param values (previously, subsequent lines were lost) 2009-09-07 14:07:05 -04:00
Bryan Helmkamp ad06a777fb Re-introduce VERSION constant, but don't make it dependent on the VERSION file 2009-09-07 13:25:33 -04:00
Bryan Helmkamp 756a0c62ba Make build task depend on gemspec. Closes GH issue #15 2009-09-07 13:22:57 -04:00
Bryan Helmkamp 63591a8c30 History 2009-09-07 13:18:57 -04:00
Bryan Helmkamp ecaed5ff93 Merge commit 'm3talsmith/master' into gh_18 2009-09-07 13:16:53 -04:00
Bryan Helmkamp b0a8922eb4 History 2009-09-07 13:08:34 -04:00
Bryan Helmkamp 2490c247d2 More clarification of select option locating behavior.
TODO: Ensure the other locators are all matching on text, not HTML
2009-09-07 12:53:06 -04:00
Bryan Helmkamp 00c49a0521 Simplify select option matching code. Minor behavior change:
Valid: select "Peanut Butter & Jelly"
  Invalid: select "Peanut Butter &amp; Jelly"
2009-09-07 12:44:54 -04:00
Bryan Helmkamp b7ea26841e Add some development dependencies (needed for running the specs) 2009-09-07 12:44:42 -04:00
Kieran Pilkington a8d0cebde3 Various improvements, refinements, and bugfixes for select field usage.
Multiple select boxes are now handled a lot better.
* You can now select more than one field (where as previously, the last one select would override previous selections)
* You can now unselect a value. It works like select, takes the same params, but removes the selection value

Issues regarding ampersands in values have been resolved.
* Values are now unescaped when the to_param method is run on elements, to make assertions less complicated
* Locating an option with ampersand values now works as expected (it will check for both escaped and unescaped occurrences)

Bunch of new specs and 3 broken pending ones have now been fixed. [#145 status:resolved]
2009-08-31 18:34:04 +12:00
Bryan Helmkamp 98efa54900 Whitespace 2009-08-29 16:09:30 -04:00
Bryan Helmkamp 49c25027e9 History 2009-08-29 16:05:56 -04:00
Bryan Helmkamp 6fd9732b4e Spec giving me trouble -- removing for now 2009-08-29 16:04:04 -04:00
Bryan Helmkamp b9466df773 Merge commit 'djanowski/fix_logger' 2009-08-29 15:57:58 -04:00
Michael Christenson II 3255c9edf0 Forces an integer to fix Issue #18 2009-08-27 11:54:03 -04:00
Bryan Helmkamp 5b90488f29 Revert "Regenerated gemspec for version 0.5.2"
This reverts commit f1cd50d615.
2009-08-27 01:02:01 -04:00
Bryan Helmkamp f1cd50d615 Regenerated gemspec for version 0.5.2 2009-08-27 00:59:53 -04:00
Bryan Helmkamp e18ef197b5 Move selenium integration code to webrat/integrations/selenium so it's automatically required 2009-08-20 00:09:03 -04:00
Bryan Helmkamp 755abb7e07 History 2009-08-19 23:44:33 -04:00
Bryan Helmkamp 723f4356b9 Move rspec-rails integration code to webrat/integrations/rspec-rails 2009-08-19 23:42:58 -04:00
Bryan Helmkamp 2fc9f3f7f9 Move adapters to webrat/adapters, and Rails and Merb integration code into webrat/integrations 2009-08-19 23:42:54 -04:00
Bryan Helmkamp 610f0fc217 Webrat doesn't need to worry about StringIOs
...or, we're missing a test and this is going to help us find it
2009-08-19 23:14:13 -04:00
Bryan Helmkamp 11f30d1d2e Dropping support for Hpricot and REXML 2009-08-19 23:14:13 -04:00
Simon Rozet 997ff97405 MerbSession now use RackSession under the hood 2009-08-19 23:14:08 -04:00
Bryan Helmkamp ab745d786c Require rubygems in rakefile for convenience
This does not break the "Don't require rubygems" spirit,
because it's not creating a dependency in the Webrat runtime code
2009-08-19 22:02:19 -04:00
Bryan Helmkamp 759d7e4581 Regenerated gemspec for version 0.5.1 2009-08-18 00:42:57 -04:00
Bryan Helmkamp 35deb84a18 Version bump to 0.5.1 2009-08-18 00:42:31 -04:00
Bryan Helmkamp 887d2b07f3 Prep for 0.5.1 release 2009-08-18 00:42:24 -04:00
Bryan Helmkamp ad0c846f17 History 2009-08-18 00:39:53 -04:00
Damian Janowski 4a949e0e5a Fix logger issue when running inside Cucumber. 2009-08-14 13:05:20 -03:00
Bryan Helmkamp 66251b66ae Cleanup session initializaton in Webrat::Methods 2009-08-12 22:05:04 -04:00
Bryan Helmkamp ec43bb9546 Selenium is a session type, not an adapter type 2009-08-12 21:44:02 -04:00
Bryan Helmkamp 2e6bef3b57 Rename TestSession to TestAdapter 2009-08-12 21:42:01 -04:00
Bryan Helmkamp 17713c9036 MechanizeAdapter doesn't need to inherit from Session 2009-08-12 21:39:32 -04:00
Bryan Helmkamp 0412543e5a Add very basic spec for Mechanize 2009-08-12 21:37:15 -04:00
Bryan Helmkamp e4ea9134a7 Rename MechanizeSession to MechanizeAdapter 2009-08-12 20:54:29 -04:00
Bryan Helmkamp 89ec303db5 Rename RailsSession to RailsAdapter 2009-08-12 20:52:57 -04:00
Bryan Helmkamp 986682488e Rename MerbSession to MerbAdapter 2009-08-12 20:50:55 -04:00
Bryan Helmkamp 22a06000f9 Introduce session_class method 2009-08-12 20:44:32 -04:00
Bryan Helmkamp a8c5af2b7a Rename session_class method to adapter_class 2009-08-12 20:43:44 -04:00
Bryan Helmkamp b0b88a0d82 Rename SinatraSession to SinatraAdapter 2009-08-12 20:40:44 -04:00
Bryan Helmkamp 561525dd81 Rename RackSession to RackAdapter 2009-08-12 20:39:35 -04:00
Bryan Helmkamp 3670b19f66 Remove duplicate branch for :sinatra mode 2009-08-12 20:25:25 -04:00
Bryan Helmkamp d55802d26e History 2009-08-12 20:17:16 -04:00
Bryan Helmkamp 74d470ff10 Merge commit 'sr/rack-upload' 2009-08-12 20:16:57 -04:00
Bryan Helmkamp 25e46a00f6 History 2009-08-12 20:14:01 -04:00
Bryan Helmkamp 27a773e6b0 Merge commit 'sr/mime' into sr-mime
Conflicts:
	Rakefile
	lib/webrat.rb
2009-08-12 20:12:14 -04:00
Bryan Helmkamp 3cdf378dd7 Add description to gemspec 2009-08-12 12:22:06 -04:00
Bryan Helmkamp 6a85b6e444 Regenerated gemspec for version 0.5.0 2009-08-12 12:15:14 -04:00
Bryan Helmkamp b48f9d622f Version bump to 0.5.0 2009-08-12 12:14:32 -04:00
Bryan Helmkamp 083332cdd3 Prep for 0.5.0 release 2009-08-12 12:14:18 -04:00
Bryan Helmkamp 3952d46979 History 2009-08-12 11:50:17 -04:00
Bryan Helmkamp 25c1d7c783 Merge branch 'master' into rack 2009-08-12 09:40:57 -04:00
Kamal Fariz Mahyuddin d9ebabf461 Ruby 1.9-compat - test for MiniTest::Assertion instead of T::U::AssertionFailedError 2009-08-12 14:52:01 +08:00
Bryan Helmkamp 0c7fa65880 Update gemspec 2009-08-10 20:21:38 -04:00
Bryan Helmkamp 19ca271bbd Merge branch 'master' into rack 2009-08-10 20:18:24 -04:00
Bryan Helmkamp 987766b10d Don't require rubygems at runtime (Simon Rozet) 2009-08-10 20:14:48 -04:00
Bryan Helmkamp 29186616f5 Regenerated gemspec for version 0.4.5 2009-08-10 20:01:31 -04:00
Bryan Helmkamp 796318d1ed Prep for 0.4.5 release 2009-08-10 20:01:06 -04:00
Bryan Helmkamp 8a81f16e44 Use Jeweler for gem management 2009-08-10 19:50:42 -04:00
Bryan Helmkamp 273e8c541a History 2009-07-08 14:06:03 -04:00
Brian Landau dd98b33713 Make compatable with latest version of "selenium-client" gem, version 1.2.16 2009-07-06 13:50:00 -04:00
Brian Landau 7f36cf472a Update Selenium RC Server to version 1.0.1 2009-07-06 13:43:31 -04:00
Bryan Helmkamp 11996a15dc Updating to leverage latest rack-test 2009-06-25 21:13:54 -04:00
Simon Rozet 195f9c3544 Add Rack >= 1.0 as a dependency to gemspec 2009-06-26 01:43:12 +02:00
Simon Rozet 0a2b77c9c4 Require rack in lib/webrat.rb 2009-06-26 01:42:51 +02:00
Simon Rozet 6cda9c79b4 Implement Webrat::MIME on top of Rack::Mime 2009-06-26 01:39:22 +02:00
Simon Rozet 3760867d0f Implement file uploading for :rack 2009-06-25 23:41:51 +02:00
Simon Rozet f2882ef8b2 Deprecate :rack_test 2009-06-25 22:41:05 +02:00
Simon Rozet a5a91b32e9 Deprecate the :sinatra mode
* I took the conservative approach here: the sinatra code could
  be removed but that'd cause a regression. (using Sinatra::Application
  when `app` is not defined)

* I left the sinatra tests for now; they should be removed
  once we're fully confident with rack session ones.
2009-06-25 00:38:39 +02:00
Simon Rozet 051dfe188c Make sure Webrat is usable without the Methods mixin 2009-06-25 00:09:03 +02:00
Simon Rozet 042268c6a6 Simplify Methods#webrat_adapter
It is unecessary to have a special case for the :rack mode.
2009-06-25 00:07:38 +02:00
Simon Rozet f2b3b9891b Refactor Webrat::Session
* Webrat::Session.new now take a session adapter class as it's argument and
  delegates methods such as #response_body and #response_code to an instance
  of it.

* Some of these methods will go away in the future. However, *a lot*
  of specs depends on them so I've left them for now. The plan is to
  strip down the session adapter API to these three methods:

    * request
    * response_code
    * response_body

* I had to mark a spec as pending: spec/private/rails/rails_session_spec.rb
2009-06-25 00:07:30 +02:00
Damian Janowski cbc447223c Fix form fields being double-escaped with :rack
Signed-off-by: Simon Rozet <simon@rozet.name>
2009-06-24 18:57:55 +02:00
Simon Rozet cf8d891302 More integration specs for the rack mode
One test is still pending because form fields are double-escaped.
2009-06-24 18:57:55 +02:00
Simon Rozet 4c010d1c65 Use Rack::Lint to test the rack session 2009-06-24 18:57:55 +02:00
Simon Rozet 8cda77318c Fix wrong HTTP_HOST in rack session
Webrat relies on www.example.com while Rack::Test expects example.org
2009-06-24 18:57:38 +02:00
Simon Rozet 92ec1c3d92 Require rack/test in rack session 2009-06-24 15:14:08 +02:00
Simon Rozet 0a3b979772 Rename :rack_test mode to :rack 2009-06-24 15:13:27 +02:00
Simon Rozet 3e7886ecab Get rid of RackSession
Looks like dead code
2009-06-24 15:13:16 +02:00
Bryan Helmkamp 5eeceff9e8 Removing some vestigial code from Merb session 2009-06-17 00:19:26 -04:00
Ryan Carver c11f4868a9 Don't require merb-core/two-oh for multipart support. Instead, copy the code into Webrat 2009-06-17 00:06:32 -04:00
Bryan Helmkamp 1769075c25 History 2009-06-16 17:47:55 -04:00
Bryan Helmkamp 28f19616d6 Wait for app server to boot on 0.0.0.0 instead of application_address
application_address is used to know where Selenium should navitate to,
but we always are booting app servers on 0.0.0.0 so that's where we
should verify they exist
2009-06-16 17:44:42 -04:00
Mike Gaffney 9b5b9fad62 Added attribution
[#168 state:resolved]
2009-06-15 22:44:02 -05:00
Mike Gaffney 0c9944c4d8 Merge commit 'eddd97936'
Conflicts:
	spec/integration/rails/test/integration/webrat_test.rb
2009-06-15 22:40:02 -05:00
Bryan Helmkamp 9a42304513 Revert "make label location strategy work with unescaped strings"
This reverts commit 4daf037146.

This was causing failures in the Weplay selenium suite, where we
we're using partial matches. For example:

  fill_in "Write a message", ...

When the markup was:

  <label>Write a message to Bryan ...</label>
2009-06-15 17:59:13 -04:00
Bryan Helmkamp b4ae28c48c Add JRuby to "rake multiruby" 2009-06-15 00:46:56 -04:00
Bryan Helmkamp 953d35b65a Commenting out failing Rack spec for now 2009-06-15 00:17:44 -04:00
Bryan Helmkamp ae6e3dbfc1 Adding "rake multiruby" task 2009-06-15 00:16:42 -04:00
Bryan Helmkamp d9de87c41f Remove redgreen from rails integration tests too 2009-06-15 00:16:23 -04:00
Bryan Helmkamp 9b971a15c0 Require English so we can use $LAST_MATCH_INFO instead of $~ 2009-06-15 00:08:25 -04:00
Bryan Helmkamp 6720bbb476 History 2009-06-15 00:07:09 -04:00
Bryan Helmkamp 1b5cf4b0e6 Merge commit 'origin/master' 2009-06-15 00:04:59 -04:00
Bryan Helmkamp a015931578 Comment out redgreen because it has issues on Ruby 1.9 2009-06-15 00:03:46 -04:00
Mike Gaffney a0b10d9916 requiring specific rspec version 2009-06-14 22:58:33 -05:00
Mike Gaffney 4cce77ef0d removing rspec warnings 2009-06-14 22:37:35 -05:00
Bryan Helmkamp 45e19867d6 Merge commit 'manveru/dev' into ruby19
Conflicts:
	lib/webrat/core/elements/field.rb
2009-06-14 23:31:42 -04:00
Bryan Helmkamp f8af783185 Add spec for needing to ensure Fixnum#/ return an integer in redirect checking 2009-06-14 22:03:49 -04:00
Bryan Helmkamp c2409d78a7 History 2009-06-14 21:59:32 -04:00
Bryan Helmkamp 6231e6e4d1 Merge commit 'pdcawley/master' 2009-06-14 21:58:18 -04:00
Bryan Helmkamp d620e66bd8 Use Launchy to handle opening pages in the browser with cross-platform compatibility 2009-06-14 21:38:04 -04:00
Bryan Helmkamp d60671cd3d History 2009-06-14 21:20:01 -04:00
Bryan Helmkamp 3bc2d4d1b8 Merge commit 'rcarver/merb-uploads' 2009-06-14 21:18:47 -04:00
Jakub Kuźma 8b98540aef Ruby 1.9 compatibility: Avoid calling #to_s on Arrays
[#249 state:resolved]
2009-06-14 21:05:38 -04:00
Erin Staniland b75ff6221b Added missing quote from rewrite_css_and_image_references and added support for single quotes 2009-06-14 21:01:06 -04:00
Bryan Helmkamp 78a23abb6e Merge commit 'dchelimsky/rspec-fix' 2009-06-14 20:54:02 -04:00
Mike Gaffney f4141f787d [#261 state:awaiting-patch]
added a test that shows that selenium can't click a link with text that has parens in it
2009-06-08 12:08:53 -05:00
Michael Fellinger 8d2c027089 Fix replacing of &nbsp;, aka &#160; so it works on 1.9 2009-06-07 17:03:13 +09:00
Michael Fellinger 520081c93e Don't use $LAST_MATCH_INFO since we don't require English.rb, use $~ instead 2009-06-07 17:02:32 +09:00
Michael Fellinger 48a4ec905e Make sure Field#escaped_value also works when @value is an Array on 1.9 2009-06-07 16:45:19 +09:00
Michael Fellinger 9134b09b87 Make mechanize_session_spec pass on 1.9 2009-06-07 16:34:35 +09:00
Mike Gaffney 6bfdcc54cc Fixed Spec in Test Unit more thoroghly 2009-06-05 13:51:55 -05:00
Mike Gaffney dd8688f371 moved application_server to appservers/base 2009-06-04 15:19:05 -05:00
Mike Gaffney 1910204974 refactor>moved the app servers to a directory 2009-06-04 15:13:54 -05:00
Mike Gaffney 70fadbe7fc added attribution 2009-06-04 15:05:08 -05:00
Mike Gaffney 6d74cd935e [#246 state:resolved] added external application server if you have your own started 2009-06-04 15:03:00 -05:00
Mike Gaffney a6a4a7cfd9 moving app server lookup out into a factory 2009-06-04 14:44:06 -05:00
Mike Gaffney 6816c46d47 refactored tests to be more rspeccy 2009-06-04 14:24:17 -05:00
Mike Gaffney f3a12adaa9 whitespace changes 2009-06-04 12:18:31 -05:00
Mike Gaffney e46df8c6f9 made tests cleaner and better coverage 2009-06-03 22:06:07 -05:00
Mike Gaffney 977f643dca catches spec failed exception again 2009-06-03 18:49:32 -05:00
Mike Gaffney abac2023bc removed reference to Rspec from common code 2009-06-03 17:53:19 -05:00
mike.gaffney b2c423c49c [#50 state:resolved] added deprecation warning 2009-06-03 10:01:27 -05:00
mike.gaffney 796ede6cea expand name refactor 2009-06-02 18:45:02 -05:00
mike.gaffney 28c676b4fc [#234 state:resolved] added attribution 2009-06-02 18:44:44 -05:00
Thomas Jack 4daf037146 make label location strategy work with unescaped strings 2009-06-02 18:31:33 -05:00
Thomas Jack 2ae14f78b1 expose regexp escape problem in fill_in_test 2009-06-02 17:56:12 -05:00
Thomas Jack 57326e5846 Merge branch 'master' of git://github.com/brynary/webrat 2009-06-02 17:52:14 -05:00
mike.gaffney f8f254d517 [#257 state:resolved] fixed issue with rails encodd fields in webrat 2009-06-02 17:35:29 -05:00
mike.gaffney bd1655c8e2 [#257 state:awaiting-patch] here is a test proving the issue 2009-06-02 17:23:12 -05:00
mike.gaffney 2704609224 added clicking link by title in selenium mode 2009-06-01 12:26:37 -05:00
mike.gaffney 2219ab62d3 refactoring buttons to their own controller 2009-06-01 12:25:36 -05:00
mike.gaffney 5430930bac added test for clicking link by title 2009-06-01 12:17:29 -05:00
mike.gaffney b6d26480ea [#221 state:resolved] added attribution 2009-06-01 12:01:47 -05:00
mike.gaffney b85aacae1c From larrytheliquid
Merge commit '4d05a2cf2b2de34dda0a3e805ab11b60540578df'
2009-06-01 11:59:21 -05:00
mike.gaffney 0394a1fc15 [#254 state:resolved] Added attribution 2009-05-29 17:09:55 -05:00
Matthias Marschall 9b85b6d7e0 added integration tests for all cases of click_button (by id, by html, by value, by alt for buttons and inputs of types image, button and submit) 2009-05-29 17:05:35 -05:00
Matthias Marschall 6cd734aec9 made selenium integration tests run applying larrytheliquid's patch: 627913708c 2009-05-29 17:05:35 -05:00
Matthias Marschall 73dc59cc29 click_button in selenium works now same as in headless mode 2009-05-29 17:05:34 -05:00
mike.gaffney 6fc6530a6b [#256 state:resolved] Added attribution 2009-05-29 16:36:46 -05:00
Josh Lubaway 846a90e561 Passing TextField values as plaintext to Mechanize.
Mechanize takes input as plaintext and escapes field values on its own.
If the values are escaped before they are passed to Mechanize, the values will be escaped twice.

These doubly-escaped values will result in incorrect behavior on the server side.
2009-05-29 10:42:30 -07:00
Larry Diehl 4d05a2cf2b click_link matches anchor id's with Selenium 2009-05-28 23:23:09 -07:00
Larry Diehl 627913708c Made Selenium Rails integration tests at least runnable, although
there are failures.
2009-05-28 22:40:52 -07:00
mike.gaffney c3f067b551 added missing attribution 2009-05-28 18:05:28 -05:00
mike.gaffney e0bdab3236 [#194 state:resolved] updated history 2009-05-28 18:04:40 -05:00
mike.gaffney f6b0a763a0 Merge branch 'lh_194_delegate_field_named' of git://github.com/pivotal/webrat into lh194
Conflicts:
	lib/webrat/core/methods.rb
2009-05-28 18:01:53 -05:00
Piers Cawley 58601c4653 Make Webrat::Core::Session#redirect? work in the face of rational maths.
Such as when someone uses `ruby-units' and suddenly 302/100 becomes 151/50.
2009-05-27 12:35:36 +01:00
Thomas Jack 956b43d72c Merge branch 'master' of git://github.com/brynary/webrat 2009-05-19 14:24:41 -05:00
mike.gaffney fd431f2ce8 [#242 state:resolved]
allowed changing the default timeout for browser startup in selenium
2009-05-18 16:37:45 -05:00
Mike Gaffney c6fd28d37a [#238 state:resolved] merged 2009-05-13 23:15:16 -05:00
Mike Gaffney f342142a71 Merge commit 'snusnu/master' 2009-05-13 23:12:32 -05:00
Mike Gaffney fa3b2c8bb2 [#215 state:resolved] merged 2009-05-13 23:06:26 -05:00
Luke Amdor 7f13a70b4b Added current_url to SeleniumSession to have the same api for both sessions 2009-05-13 22:33:20 -05:00
Thomas Jack 232ed36379 spec for descendant selectors in have_xpath block 2009-05-13 14:52:53 -05:00
Thomas Jack db9c5bdc77 Merge branch 'master' of git://github.com/brynary/webrat 2009-05-13 14:34:16 -05:00
snusnu 77168fd29d only require silence_stream if active_support hasn't already defined it 2009-05-13 05:01:19 +02:00
snusnu 926bcc6c66 extracted silence_stream into its own file under webrat/selenium
I don't think silence_stream.rb should be stored under
core_extensions, because the way it's implemented, it simply is
no core extension. Also, a grep through webrat source shows that
silence_stream is only used inside the selenium support. This is
why I added webrat/selenium/silence_stream.rb and require it
*before* all other selenium related files in webrat/selenium.rb.
It's necessary to include it this early, because if mode is set
to :selenium, webrat/selenium.rb is required, which in turn
requires webrat/selenium/selenium_session.rb and silence_stream
must be available before selenium_session gets required because
selenium_session already wants to silence the stream.
2009-05-13 03:35:32 +02:00
snusnu bfa250e7af Provide an implementation for silence_stream inside webrat.
I added the implementation to webrat/core/configuration.rb because
it seems to me that this always gets read first. I decided to put
it inside a util module Webrat::SilentStream and include this where
appropriate, instead of altering Kernel.
2009-05-12 18:32:30 +02:00
Bryan Helmkamp 77fa1bcdb6 Ignore *.log 2009-05-11 16:51:57 -04:00
Bryan Helmkamp 7b6b3168a2 Revert "Correct some specs that need full URLs"
This reverts commit 3e71ae3733.

Conflicts:

	spec/public/select_spec.rb
2009-05-11 16:51:42 -04:00
Bryan Helmkamp b439d7f807 Revert "Canonicalize all URLs (Shalon Wood)"
This reverts commit 755cf6e508.
2009-05-11 16:48:28 -04:00
Thomas Jack 8bedf2235d Merge branch 'master' of git://github.com/brynary/webrat 2009-05-11 00:29:49 -05:00
Bryan Helmkamp 453cb4b3eb Stripping whitespace 2009-05-11 01:27:04 -04:00
Bryan Helmkamp 3e71ae3733 Correct some specs that need full URLs 2009-05-11 00:16:38 -04:00
Bryan Helmkamp 35cbfd9643 Use Nokogiri on JRuby -- ~2x faster than REXML on JRuby for me 2009-05-11 00:13:00 -04:00
Bryan Helmkamp b5254109f1 Start on Rack::Test integration 2009-05-11 00:12:27 -04:00
Bryan Helmkamp 755cf6e508 Canonicalize all URLs (Shalon Wood) 2009-05-11 00:12:27 -04:00
Thomas Jack 9a3668be92 match descendents in have_selector/have_xpath blocks 2009-04-29 01:33:26 -05:00
David Chelimsky ffb56aab90 config for rspec in one line 2009-04-27 11:54:46 -05:00
Mutwin Kraus eddd979361 Fixed following of internal redirects when using a custom Host header
Webrat didn't properly follow internal redirects when using the Host
  header, this lets Webrat check the Host header before falling back
  to www.example.com as the current_host.
2009-04-24 23:49:11 -07:00
Ryan Carver 1a110fe908 Improve forward and backward compatibility for Merb uploads 2009-04-24 14:23:00 -07:00
Ryan Carver 26edfbc7cb Integration tests for Merb file uploads 2009-04-24 14:11:49 -07:00
Ryan Carver 09509025c3 Allow Merb to do file uploads 2009-04-24 13:56:28 -07:00
mike.gaffney 481bfe03c0 updated history 2009-04-22 12:27:24 -05:00
mike.gaffney 7d4a2035f7 Merge commit '742db2d910d7baa51487400cb339a20bd7079418' 2009-04-22 12:15:27 -05:00
mike.gaffney b1dfc1c01f updating history for Zach Dennis's fix 2009-04-16 12:37:33 -05:00
Zach Dennis 7c08390bb8 Updated regex for LabelLocator and FieldLabeledLocator to work with labels whose text ends in a non-word character like \? or # 2009-04-16 12:25:45 -05:00
Noah Davis ff42db076f Select fields with duplicate selected options sent an incorrect value 2009-04-11 13:19:59 -04:00
Bryan Helmkamp 03914fd293 Whitespace 2009-04-07 20:30:12 -04:00
Bryan Helmkamp f3f81dabdc Add "rake whitespace" task 2009-04-07 20:29:59 -04:00
Bryan Helmkamp b69b4acec4 Change setup => before 2009-04-07 20:14:59 -04:00
Bryan Helmkamp 6697ecd2d3 Prep for 0.4.4 release 2009-04-06 14:03:58 -04:00
Bryan Helmkamp 5bb587dde1 History 2009-04-06 14:03:47 -04:00
Bryan Helmkamp 996484c890 Refactoring selenium RC and app server boot code 2009-04-06 14:02:09 -04:00
Bryan Helmkamp 979418e303 History 2009-04-06 12:40:28 -04:00
Bryan Helmkamp 644478f6f0 Merge commit 'MarkMenard/master' 2009-04-06 12:39:31 -04:00
Bryan Helmkamp 50d8a7ec51 History 2009-04-06 12:33:45 -04:00
Bryan Helmkamp 91ea8cfa54 Make selenium process management code more robust and informative 2009-04-06 12:33:24 -04:00
Bryan Helmkamp 304baeb754 Change default app environment from "selenium" to "test" 2009-04-06 12:33:24 -04:00
Bryan Helmkamp aa9049953d Bump selenium-client dependency to 1.2.14 2009-03-29 16:35:27 -04:00
Balint Erdi cd49c2d939 bugfix: selenium's wait_for_element method takes the number of seconds before timing out from an option hash
Signed-off-by: Balint Erdi <balint.erdi@gmail.com>
2009-03-29 15:57:14 -04:00
pivotal 0fe3998f64 field_named correctly delegated 2009-03-17 18:21:06 -04:00
Bryan Helmkamp e2a672a767 Prep 0.4.3 release 2009-03-17 01:26:38 -04:00
Andrew Premdas 742db2d910 added spec for click links by title - functionality is already done 2009-03-13 12:09:24 +00:00
Mark Menard 0c2261d869 Add support for Rails javascript post links. 2009-03-12 15:42:20 -04:00
Mark Menard 73f4c441c1 Merge commit 'upstream/master' 2009-03-12 15:41:37 -04:00
Bryan Helmkamp 62491121c1 History 2009-03-08 18:59:15 -04:00
Bryan Helmkamp d1a2c80ab8 Merge commit 'sr/sinatra' into sr_sinatra 2009-03-08 18:54:21 -04:00
Simon Rozet 90baf3311c Sinatra now provides sensible options for testing
In the lastest release, 0.9.1:

* Set sensible defaults on Default for test env [1]
  5a33a9586f

* Set :environment to :test in TestHarness
  9af37724e0

* Set :environment to :test when Sinatra::Test is included
  93b19a3492

[1] Only Sinatra::Default provides special options for testing. If you subclass
    Sinatra::Base, you'll have to set them yourself.

foo
2009-03-08 23:41:34 +01:00
Bryan Helmkamp 5dc24c613e Merge branch 'master' into sr_sinatra 2009-03-08 14:59:54 -04:00
Mark Menard c647ae98bb Memoize WWW::Mechanize instance. 2009-03-05 17:45:56 -05:00
Luke Melia 72123c1cec When faced with a label with no for attribute, that contains a hidden field and another field, as can be the case in Rails 2.3's checkbox view, webrat now locates the non-hidden field. 2009-03-01 01:44:35 -05:00
Matthew Ford 740bb293e3 Fix for #161 When using Rails 2.3 it uses Rack::Utils to parse params 2009-02-28 23:08:07 -05:00
Simon Rozet 4e07f5b654 Fix following of absolute redirect URL in Sinatra
What's going on when the app redirects to an absolute URL?

* Sinatra relies on Rack::MockSession which sets SERVER_NAME to
  "example.org" [1] on request it makes. However, Webrat expects
  it to be "www.example.com"

* In MyClassyApp, the redirect URL is made out of Rack::Request#url [2]
  which uses  SERVER_NAME, which is set to "example.org" by Rack::MockSession.
  As a result, Webrat see it as an external redirect and don't follow it.

NOTE:

* SERVER_NAME is stricly equivalent to HTTP_HOST [3]
* This could have been fixed in Webrat::Session too. I'am not sure
  that it won't affect other frameworks so I left it intact.

      def request_page(url, http_method, data) #:nodoc:
         h = headers
         h['HTTP_REFERER'] = @current_url if @current_url
  +      h['HTTP_HOST']    = 'www.example.com'

[1] 5c00dd698e/lib/rack/mock.rb (L79)
[2] 5c00dd698e/lib/rack/request.rb (L201)
[3] 5c00dd698e/lib/rack/request.rb (L72)
2009-02-28 03:30:26 +01:00
Simon Rozet 7d7c32256d Support for "modular" Sinatra app style
Since Sinatra 0.9, apps can be ancapsulated in a class ("modular" style)
or be on the top level, just like before ("classic" style)

* http://wiki.github.com/brynary/webrat/sinatra
* http://www.sinatrarb.com/extensions.html
2009-02-28 03:30:25 +01:00
Bryan Helmkamp 00433bafe5 History 2009-02-27 20:45:51 -05:00
Bryan Helmkamp 4115c99c9b Merge branch 'master' into atmos 2009-02-27 20:41:05 -05:00
Bryan Helmkamp b7e0d6f8e6 Prep for 0.4.2 release 2009-02-24 12:29:05 -05:00
Bryan Helmkamp e32a208b7f Fix warning caused by Nokogiri deprecating CSS::Parser.parse (Aaron Patterson) [#176 state:resolved] 2009-02-23 22:19:02 -05:00
Bryan Helmkamp aec889a14d Always deal with one query selector (a String, not an Array) 2009-02-23 22:14:58 -05:00
Bryan Helmkamp dad3da195c Bumping nokogiri dependency version to 1.2.0 2009-02-23 21:18:17 -05:00
Bryan Helmkamp 18c60f4e51 Refactoring XPath manipulation 2009-02-23 20:52:17 -05:00
Bryan Helmkamp 29c40bd73c Pulling attribute conditions up from have_selector to have_xpath 2009-02-23 20:47:02 -05:00
Bryan Helmkamp 1625e3e9ba Pulling :content functionality up from have_selector into have_xpath 2009-02-23 20:22:36 -05:00
Bryan Helmkamp a688c28b19 Extracting xpath_escape method 2009-02-23 20:21:23 -05:00
Bryan Helmkamp 9761b64b60 Pulling :count option up from have_selector to have_xpath 2009-02-23 20:18:36 -05:00
Bryan Helmkamp 66d39b851c Allow have_xpath to accept options 2009-02-23 20:15:29 -05:00
Bryan Helmkamp 2296cadb93 Pulling features up from have_tag into have_selector 2009-02-23 20:11:25 -05:00
Corey Donohoe 120a53dced small doc fixup to explain how to use different application frameworks with selenium 2009-02-23 14:21:42 -07:00
Bryan Helmkamp d96899be8c Remove extra whitespace from contain failure message 2009-02-23 11:19:09 -05:00
Corey Donohoe ec06c76b91 use bin/merb if it's available for appserver startup 2009-02-18 12:31:52 -07:00
Corey Donohoe 92565d3bc4 use application_environment in merb also 2009-02-18 12:16:19 -07:00
Bryan Helmkamp b4687c29d5 Break out specs for matchers into separate files 2009-02-15 19:47:12 -05:00
Bryan Helmkamp 17a8bc7b66 Adding :count option to have_tag 2009-02-15 19:41:44 -05:00
Bryan Helmkamp 932fdab884 Get quoting working for content 2009-02-15 19:32:25 -05:00
Bryan Helmkamp 7ba620f38b Whitespace 2009-02-15 18:57:53 -05:00
Corey Donohoe 4fb9406154 remove commented line that serves no purpose 2009-02-15 15:54:04 -07:00
Corey Donohoe 63337d4476 it helps if i make sure the spec suite still passes :\ 2009-02-15 14:41:54 -07:00
Corey Donohoe 69dfa5022a Webrat.configuration.application_type => Webrat.configuration.application_framework 2009-02-15 14:40:17 -07:00
Corey Donohoe 7692930769 clean up constant definitions for rails and fix merb port fubar on selenium appserver stop 2009-02-15 14:37:38 -07:00
Corey Donohoe 9066d2a9cd add specs for starting and stopping appservers, covers rails, sinatra and merb 2009-02-13 20:26:44 -07:00
Corey Donohoe 4bf49a5163 allow picking your appserver type via a configuration option, not discovering framework specific files in the current working directory. also start rack apps with the application port parameter 2009-02-11 11:17:43 -07:00
Corey Donohoe 8fbcbef180 better handling for starting/stopping the server 2009-02-11 10:09:23 -07:00
Corey Donohoe 82eabc31ee small fixup for sinatra + selenium, use rackup instead of mongrel_rails if config.ru exists 2009-02-11 09:25:39 -07:00
Peter Jaros 24eab77ecd Accept do/end blocks in matchers. [#157 state:resolved] 2009-02-09 00:31:17 -05:00
Bryan Helmkamp 7fe667da73 Removing HashWithIndifferentAccess
Doesn't seem to be required, according to our integraton specs
2009-02-09 00:13:41 -05:00
Bryan Helmkamp a89e3ee612 History [#159 state:resolved] 2009-02-08 21:05:58 -05:00
Bryan Helmkamp 7fc6a79bee Merge commit 'teejayvanslyke/master' into lh_159 2009-02-08 21:03:40 -05:00
Bryan Helmkamp e97f7fafc5 Add a spec for two checkboxes with the same name (array style) 2009-02-08 20:58:43 -05:00
Bryan Helmkamp 4769a5f90b Detect infinite redirects and raise a Webrat::InfiniteRedirectError (Daniel Lucraft) 2009-02-08 20:54:00 -05:00
Bryan Helmkamp e5ae16367c Prep for 0.4.1 release 2009-01-31 17:58:17 -05:00
Bryan Helmkamp d9de0c4e78 Remove gemspec. I don't want GitHub to build gems... 2009-01-31 17:57:35 -05:00
Bryan Helmkamp aa97b063f7 History 2009-01-31 17:31:35 -05:00
Lee Bankewitz 56e6d15811 add uncheck to selenium_session 2009-01-30 15:15:22 -05:00
T.J. VanSlyke ea8e1910d1 Added single-quotes around --chdir argument to mongrel_rails call, as
webrat bombs with a file not found error if RAILS_ROOT contains a space.
2009-01-30 11:37:43 -08:00
Noah Davis 49e86d103f comment out have_tag from selenium matcher which overrides rails' have_tag
partially reverts 483559f279
2009-01-28 14:34:24 -05:00
Bryan Helmkamp c25885afc0 History 2009-01-27 19:16:32 -05:00
Bryan Helmkamp 7f9df54838 Merge commit 'lenalena/master' into lh_139 2009-01-27 19:13:53 -05:00
Bryan Helmkamp d2d8de7963 History 2009-01-27 19:11:28 -05:00
Bryan Helmkamp 91edb22b81 History 2009-01-25 20:02:40 -05:00
Bryan Helmkamp 33509ef575 Remove stray require of ruby-debug 2009-01-25 19:50:58 -05:00
Bryan Helmkamp 238bfb469e Use redgreen when running rails integraton tests if available 2009-01-25 19:48:02 -05:00
Bryan Helmkamp 0039bf4d4b Check exit code of spec:jruby when running precommit 2009-01-25 19:46:22 -05:00
Bryan Helmkamp 6836115308 History 2009-01-25 19:45:58 -05:00
Mike Gaffney 3d5dd1343c turning off have_tag test for now until we figure out whether we want it or not. Making integration not run the selenium tests for now. Need a eventually framework for test::unit 2009-01-25 18:30:03 -06:00
Mike Gaffney 8d9d907e73 have_tag is built into rails and rspec and we don't want to overload those.
Please use assert_contain or assert_select
Revert "Make have_tag work in rails as well as Merb"

This reverts commit 6e7609e01c.
2009-01-24 13:01:41 -06:00
Noah Davis f956bea7dd Adding rescue from Webrat::TimeoutError in selenium matchers which allows NegativeMatchers to behave correctly 2009-01-24 01:44:05 -05:00
Mike Gaffney 18fa3ab11c Merge branch 'master' of git@github.com:gaffo/webrat
Conflicts:
	History.txt
2009-01-23 22:55:32 -06:00
Amos King 40280a4a0d fix history to be in correct version. 2009-01-23 22:53:29 -06:00
Mike Gaffney fc4ba75e22 Merge branch 'master' of git@github.com:gaffo/webrat 2009-01-23 22:46:16 -06:00
Amos King 099341cede Forgot to add Mike 2009-01-23 22:42:34 -06:00
Mike Gaffney f4f0e3b6a7 Merge branch 'master' of git@github.com:brynary/webrat 2009-01-23 22:35:46 -06:00
Amos King 483559f279 Makes have_tag work outside of Merb. 2009-01-23 21:32:54 -06:00
Amos King 0a021059d6 Added to rails test for have_tag 2009-01-23 21:13:52 -06:00
Amos King 6e7609e01c Make have_tag work in rails as well as Merb 2009-01-23 21:13:13 -06:00
Amos King 118b522662 moved have content 2009-01-23 21:03:19 -06:00
Amos King 3a5d34e759 Moved have selector 2009-01-23 21:01:21 -06:00
Amos King 5a91f10a99 Began moving selenium matchers to their own files to be consistent with core matchers and for maintainability. 2009-01-23 20:59:30 -06:00
Amos King 0b8e378fb2 change to use rails label tag for test. 2009-01-23 20:56:16 -06:00
Amos King 5b8e451272 forgot to update History file 2009-01-23 20:37:35 -06:00
mike.gaffney cbddebd01c Merge branch 'lh_82' of git@github.com:gaffo/webrat 2009-01-23 16:23:12 -06:00
Amos King a1ef306838 update Rakefile to run test_units with the new test task 2009-01-23 16:13:43 -06:00
Noah Davis 996eedb0d2 Switch to using selenium.click instead of .check when checking a checkbox 2009-01-23 17:08:04 -05:00
Amos King 8c0facc5af cleanup and tests closes LH #82 2009-01-23 16:05:33 -06:00
Amos King 813adcc238 Remove the rails selenium test directory and change rake tasks for selenium and rails modes to run the same tests. The end goal should be that the same tests run in both Seleium and Webrat. 2009-01-23 15:37:26 -06:00
Amos King da59584cdf add the ability for selenium mode to create pids dirs 2009-01-23 15:34:51 -06:00
Amos King 2c9b546a83 Merge branch 'lh_120_tests_with_selenium' of git@github.com:gaffo/webrat into lh_82
Conflicts:
	spec/integration/rails/test/integration/webrat_test.rb
2009-01-23 15:11:16 -06:00
Zach Dennis 0272e81847 Fixed issue where webrat was only using relative paths when making requests for Rails apps. This borked Rails apps that use subdomains [John Hwang/Zach Dennis] 2009-01-20 21:48:48 -05:00
Josh Knowles 7a59353c78 Unfortunately this commit breaks any Rails specs which pass anchor tags. I like the concept, but I'd prefer to work on this post 0.4.1 once I have a bit more time to work out the failures in our referance app.
This reverts commit 4fc2b7eb7e.
2009-01-20 20:08:57 -05:00
Adam Greene 4fc2b7eb7e removing the normalization of url's for the rails session. stipping them of host, port, and anchors is not really needed, especially since josh's redirect change to stop when going to a different host. See comments here: http://webrat.lighthouseapp.com/projects/10503-webrat/tickets/132 2009-01-20 19:30:28 -05:00
Adam Greene 4e3cf59920 adding a helper method to make it easier to see where the user was redirected_to 2009-01-20 19:30:22 -05:00
Adam Greene ce36e5890f lets follow redirects that are on the same domain but a different subdomain... 2009-01-20 19:30:16 -05:00
Bryan Helmkamp c06fa90864 History 2009-01-20 00:37:03 -05:00
Bryan Helmkamp e53c64f763 Setup deprecated writers for the selenium_environment= and selenium_port= config methods 2009-01-20 00:32:19 -05:00
Bryan Helmkamp 9a2302e9af History 2009-01-20 00:27:38 -05:00
Bryan Helmkamp d60f524df1 Merge commit '1bfe7634f8bb93472f4f53715d43916a8ff1569f' 2009-01-20 00:26:36 -05:00
Bryan Helmkamp 0204c2766d Change query params parser to work with Edge Rails 2009-01-20 00:25:52 -05:00
Bryan Helmkamp d64bba627e History 2009-01-19 20:03:21 -05:00
ichverstehe 1bfe7634f8 sinatra 0.9 support 2009-01-19 23:51:01 +01:00
Kyle Hargraves 6529a016d1 Labels should only search for fields within the current scope 2009-01-19 13:45:36 -06:00
Bryan Helmkamp 14d114ce1d Ensure the previous pages params aren't passed through redirect 2009-01-19 13:56:22 -05:00
Bryan Helmkamp ced63f6e5a Don't install RDoc when installing locally built gem 2009-01-19 13:48:58 -05:00
Bryan Helmkamp b8b4a614c4 Use reload instead of deprecated reloads in spec 2009-01-19 13:40:58 -05:00
Bryan Helmkamp 8352985d08 Updating History for 0.4.0 release 2009-01-18 17:27:31 -05:00
Bryan Helmkamp f7b4e673cd reloads is deprecated, not reload 2009-01-18 17:19:46 -05:00
Bryan Helmkamp 9056255abe Updating gemspec 2009-01-18 17:09:13 -05:00
Bryan Helmkamp bbf6cf06c2 Bump version number to 0.4.0 2009-01-18 17:08:12 -05:00
Kyle Hargraves 2b38b78724 field_labeled() should disregard labels without matching fields 2009-01-18 15:57:08 -06:00
Bryan Helmkamp cbd323ac37 More info in the Unknown mode error message 2009-01-18 16:45:24 -05:00
Bryan Helmkamp f92f9bead8 Parse content as HTML (unless the Content-Type is XML) 2009-01-18 16:34:42 -05:00
Bryan Helmkamp 4720a79d3c Bumping version to 0.3.999.1 in prep for 0.4 coming later today 2009-01-18 16:26:32 -05:00
Bryan Helmkamp 743d787164 Ensure setting mode as a string works too 2009-01-18 16:25:35 -05:00
Bryan Helmkamp 00d0d7b438 Temporary shim to support Merb's require statement for Webrat 2009-01-18 16:20:58 -05:00
Bryan Helmkamp fdb94f399c Allow multiple configuration blocks without dropping previous configuration.
If you really want to start with a default configuration use:

  Webrat.configure(Webrat::Configuration.new) do |config|
    ...
  end
2009-01-18 16:15:56 -05:00
Bryan Helmkamp 0b07dfedcd Add docs for field_labeled 2009-01-18 16:05:27 -05:00
Bryan Helmkamp 6676ae2da9 Adding integration test for field_labeled 2009-01-17 17:13:20 -05:00
Bryan Helmkamp 9be3f772bf Whitespace 2009-01-17 17:03:31 -05:00
Bryan Helmkamp 45c5a6a34d Remove a couple pending specs 2009-01-17 17:02:05 -05:00
Zach Dennis cdf9908f9e Fixed bug where Scope was creating a new DOM rather than re-using the existing DOM. [#105 state:resolved] 2009-01-17 16:59:12 -05:00
Bryan Helmkamp ebd9d8ed52 Merge commit 'gaffo/lh_116_selenium_asserts' into lh_116
Conflicts:
	History.txt
2009-01-17 16:39:29 -05:00
Bryan Helmkamp 9133fdc0e2 Need test/unit to test assert functionality 2009-01-17 16:34:00 -05:00
Bryan Helmkamp 55bc6b8e00 Merge commit 'gaffo/lh_123' into lh_123
Conflicts:
	History.txt
2009-01-17 16:27:39 -05:00
Bryan Helmkamp 1731681e79 Merge commit 'cornel/lh_110'
Conflicts:
	History.txt
2009-01-17 16:10:34 -05:00
George Ogata 9ea7d94621 Add documentation for set_hidden_field, click_area, and submit_form [#122 state:resolved] 2009-01-17 13:40:03 -05:00
Bryan Helmkamp fb03d03c5f History 2009-01-17 13:34:15 -05:00
Bryan Helmkamp 030412bd3f Minor refactoring to extract rails_request_parser 2009-01-17 13:34:06 -05:00
Bryan Helmkamp 7f38666325 Merge commit 'marcenuc/lh_107_request_parser_2_3_fix' into lh_107 2009-01-17 13:30:40 -05:00
Bryan Helmkamp 3e3d8e3659 Raise a Webrat::NotFoundError if the scope passed to #within doesn't exist [#90 state:resolved] 2009-01-17 13:27:32 -05:00
Bryan Helmkamp 8b652bd036 Ignore *.tmproj 2009-01-17 13:20:22 -05:00
Bryan Helmkamp 7a7cb3f002 Support passing an ActiveRecord model to #within when in Rails mode [#68 state:resolved] (Luke Melia) 2009-01-17 13:18:42 -05:00
Bryan Helmkamp 21aef01222 Merge history for 0.3.X releases into trunk 2009-01-17 12:47:24 -05:00
Amos King 04b765976b change matchers to use assert so that assertion count is incremented 2009-01-14 11:38:38 -06:00
Amos King f841ced43d add line in History for fix #123 2009-01-14 11:02:42 -06:00
Amos King 50c5d50ca7 make asserts count for have_xpath 2009-01-14 11:01:44 -06:00
Amos King 47c0b9520f make asserts count for have_tag 2009-01-14 11:01:33 -06:00
Amos King e864d56079 make asserts count for have_selector 2009-01-14 11:01:20 -06:00
Amos King 3707262e72 make asserts count for assert_contain 2009-01-14 11:00:42 -06:00
Amos King ea930106b6 remove commented code and make assert_contain use a true assertion 2009-01-14 10:58:48 -06:00
Amos King 652610381a added selenium test for assert_selector 2009-01-13 22:48:57 -06:00
Amos King fd860a2e6d added rails test for assert_selector 2009-01-13 22:48:06 -06:00
Amos King a32ec70d7f added xpath test to selenium 2009-01-13 22:45:26 -06:00
Amos King 647eb4cb6f add test for assert_xpath 2009-01-13 22:43:31 -06:00
Amos King 2d065e8a2d add test for click_link with id to selenium 2009-01-13 22:43:14 -06:00
Amos King 0aa5fda61d added click link test to selenium 2009-01-13 22:35:58 -06:00
Amos King 2510e7d43d added clicking link by id 2009-01-13 22:34:47 -06:00
Amos King 3902573d3e add a link to the rendered text and add a test for clicking it 2009-01-13 22:33:47 -06:00
Amos King 9745673f1c Revert "remove commented code and make assert_contain use a true assertion"
This reverts commit 114db434182bbf9ad5b2737d181048bab363f055.
2009-01-13 22:30:52 -06:00
Amos King cdd390a19d remove commented code and make assert_contain use a true assertion 2009-01-13 22:30:52 -06:00
Amos King a396758da4 fixed rakefile so the tasks will run the correct mode, and so there is a task to run both modes. 2009-01-13 07:57:20 -06:00
Mike Gaffney 758e323f89 breaking up selenium from rails_webrat tests for the moment 2009-01-13 00:26:49 -06:00
Mike Gaffney c0220232c7 broke selenium mode tests out into a seperate file. 2009-01-13 00:13:17 -06:00
Mike Gaffney c1b49f36ea working on getting standardized for the specs 2009-01-12 23:31:14 -06:00
Mike Gaffney 86089d90b6 Merge commit 'origin/lh_116_selenium_asserts' into test_unit_integrations 2009-01-12 23:14:37 -06:00
Mike Gaffney f7f8c91cb7 getting selenium up and running 2009-01-12 22:54:33 -06:00
Mike Gaffney f2a202ae5e adding pids directories 2009-01-12 22:44:53 -06:00
Mike Gaffney f835bac31b cleaning out app and getting selenium mode to work 2009-01-12 22:42:35 -06:00
Mike Gaffney bdf660aecb Renamed the task for seleniumw 2009-01-12 22:30:36 -06:00
Mike Gaffney a8a63472bc breaking the test mode out into a specific test modes 2009-01-12 22:30:03 -06:00
Amos King 8b6477a0c6 change History file 2009-01-12 15:57:42 -06:00
cornel.borcean 0a75799079 update History file 2009-01-12 15:48:26 -06:00
Amos King 714d8679ed change attr_accessor :mode to attr_reader since there is a writer created after 2009-01-12 15:41:56 -06:00
cornel.borcean c79d2216b2 added selenium_browser_key to allow running on more than firefox, and completed the ability to configure to work with selenium grid."
"
2009-01-12 15:15:11 -06:00
cornel.borcean e49c341fc0 implemented start and stop selenium server only if the selenium_server_address is nil 2009-01-12 14:17:05 -06:00
cornel.borcean 0edffe0ac4 added selenium_server port and address and application address for configuring selenium more dynamically 2009-01-12 12:50:53 -06:00
cornel.borcean 0ce92dfcd8 changed selenium_environment to application_environment and deprecated selenium_environment and selenium_port 2009-01-12 12:32:14 -06:00
cornel.borcean 8932544d46 changed description for the application_port variable 2009-01-12 12:21:24 -06:00
cornel.borcean 33d2cdcc53 changed selenium_port to application_port to reflect what the variable is used for ... 2009-01-12 12:13:22 -06:00
Amos King d4008ebc06 oops didn't notice I was using the wrong matchers. Matchers now using Selenium mode. 2009-01-09 23:13:57 -06:00
Amos King 928b224237 Revert "include Webrat::Matchers in selinium mode"
And Revert "getting assert_* to work with selenium"
2009-01-09 23:11:33 -06:00
Amos King 10b31be511 remove duplicated code from the Has Content matchers in selenium matchers file. 2009-01-09 22:14:12 -06:00
Amos King fbb74a5a98 include Webrat::Matchers in selinium mode 2009-01-09 22:13:34 -06:00
Lena b4d85cb50b Added recognition of input tags with type button, which are generated by the Rails submit_to_remote helper 2009-01-07 12:27:47 +01:00
Marcello Nuccio 076e198287 In rails-2.3 parse_query_parameters is in RequestParser 2009-01-07 03:17:26 +01:00
Mike 7fa51ab8c4 Merge branch 'lh_86_assert_contains' of git@github.com:gaffo/webrat into lh_86_assert_contains 2009-01-05 13:30:56 -06:00
Mike d354c218d0 had additional files that were moved earlier 2009-01-05 13:19:26 -06:00
Mike be82666a95 had additional files that were moved earlier 2009-01-05 13:18:52 -06:00
Mike 01cf6cea80 credit where credit is due 2009-01-05 13:08:03 -06:00
Mike 7bfa4c55c0 Merge branch 'lh_86_assert_contains' of git@github.com:gaffo/webrat into lh_86_assert_contains 2009-01-05 13:06:53 -06:00
Amos King 021f197abc change assert_tag and assert_no_tag to assert_have_tag and assert_no_tag so it won't conflict with rails and so that it will be more like the matchers. 2009-01-05 13:03:08 -06:00
Amos King ff00ae10ea add have to assert_selector and assert_no_selector for consistency. 2009-01-05 12:59:56 -06:00
Amos King f814b79ac1 change assert_xpath and assert_no_xpath to be assert_have_xpath and assert
_have_no_xpath to be closer to the rspec matcher.
2009-01-05 12:58:40 -06:00
Mike 7901c7503a Merge branch 'master' of git://github.com/brynary/webrat into lh_86_assert_contains 2009-01-05 12:33:19 -06:00
Amos King 4e0845c8db Added assert_xpath and assert_no_xpath for Test::Unit support. 2009-01-05 12:23:48 -06:00
Josh Knowles 9825aee47e Don't follow external redirects 2009-01-04 23:56:52 -05:00
Nicolas Sanguinetti 4565a3cea6 Unescape the values passed to the sinatra test helpers 2009-01-04 22:36:21 -05:00
Josh Knowles 34ea3e64b8 Sinatra integration tests for following redirects 2009-01-04 22:34:47 -05:00
Josh Knowles c3120833b0 Merge branch 'foca/master' 2009-01-04 21:57:25 -05:00
gaffo fece459f5f added assert_selector 2009-01-04 18:00:18 -06:00
gaffo cf1589823d added assert_tag, assert_no_tag 2009-01-04 17:42:54 -06:00
gaffo 0f0dab0b0b Upaded to webrat newest
Signed-off-by: gaffo <mike@uberu.com>
2009-01-04 15:21:14 -06:00
Amos King fe5d183e69 backed out will add in again as a different feature 2009-01-02 14:36:16 -06:00
Amos King 45bd577955 fix selenium matchers to only overide needed methods from the oriinal matchers so that I don't have to write the same methods again for selenium mode. 2009-01-02 14:31:43 -06:00
Mike b77c33b865 added delegator for response_body to session so it is accessible from integration test when using test::unit 2009-01-02 13:05:27 -06:00
Amos King b3d6c9d89b assert_contain and assert_not_contain fully functional 2008-12-31 17:01:46 -06:00
Josh Knowles e19b1cc323 Rails and Merb integration tests for following redirects 2008-12-29 23:14:26 -05:00
Josh Knowles e77495bc04 Refactor redirect handling as Merb response doesn't support the redirect? method. All integration specs now passing again. 2008-12-29 22:45:55 -05:00
Josh Knowles b222d3fde3 Allow the running of Rails/Merb integration specs independently 2008-12-29 22:15:03 -05:00
Josh Knowles 7044eb5863 Make merb integration test load 'local' webrat, instead of the gem. 2008-12-29 22:14:58 -05:00
Nicolas Sanguinetti 7258ea3349 Make rails integration test load 'local' webrat, instead of the gem. 2008-12-29 22:14:52 -05:00
Josh Knowles ce364d1663 Refactor redirect support out of RailsSession & SinatraSession and into Session#request_page 2008-12-29 21:19:13 -05:00
Josh Knowles a569738542 Running rake spec should run all specs (even those in sub-directories) 2008-12-29 20:54:59 -05:00
Kieran Pilkington 0938c6dafc bugfix: when h was nil (which it was for all my tests), everyone would fail with nil.[]= errors. Making sure we at least have a blank hash fixes this. 2008-12-29 19:27:30 -05:00
Nicolas Sanguinetti 499dcefefe Add integration tests for sinatra 2008-12-29 06:41:50 -02:00
Nicolas Sanguinetti 33e853710e Make rails integration test load 'local' webrat, instead of the gem. 2008-12-29 06:41:30 -02:00
Nicolas Sanguinetti 25c3fd73db Rename sinatra session spec so it matches the other ones 2008-12-29 06:14:27 -02:00
Nicolas Sanguinetti 47bc51b864 Merge commit 'brynary/master' 2008-12-29 06:11:04 -02:00
Nicolas Sanguinetti a058c8e5cc Fix sinatra spec for redirects 2008-12-29 06:05:04 -02:00
Bryan Helmkamp 2562942b6d Adding merb app for integration testing 2008-12-29 02:10:05 -05:00
Bryan Helmkamp add38820e5 Adding two tests for Rails integration 2008-12-29 01:30:26 -05:00
Bryan Helmkamp 39e0200608 Adding a Rails app for integration testing 2008-12-29 01:11:41 -05:00
Bryan Helmkamp b4dd150250 Moving spec/webrat to spec/private and spec/api to spec/public (a la Merb) 2008-12-29 01:06:04 -05:00
Bryan Helmkamp 828857f88e Bumping nokogiri depenency version 2008-12-29 00:49:24 -05:00
Nicolas Sanguinetti 422c6aea89 Use request_page to handle sinatra redirects
This should make current_url and keeping the referrer work as expected
2008-12-29 03:37:41 -02:00
Nicolas Sanguinetti 6704d487bc Disable sinatra's app run and reload 2008-12-29 03:37:12 -02:00
Nicolas Sanguinetti 6d108393be Allow accessing the request and response from SinatraSession 2008-12-29 01:40:14 -02:00
Bryan Helmkamp 2ead102f54 Merge commit 'joshknowles/master' 2008-12-28 21:15:31 -05:00
Josh Knowles 4b6558e7e5 Properly set referer and redirect to proper location 2008-12-28 21:12:34 -05:00
Bryan Helmkamp a018af99ff Remove references to should_see and should_not_see, which don't exist 2008-12-28 21:05:22 -05:00
Bryan Helmkamp 29274f9b4b Merge commit 'joshknowles/master'
Conflicts:
	lib/webrat/rails.rb
	spec/webrat/rails/rails_session_spec.rb
2008-12-28 19:35:42 -05:00
Bryan Helmkamp f409ec3ecb Better error message if Webrat mode is unknown 2008-12-28 14:24:24 -05:00
Bryan Helmkamp 61b864f113 History 2008-12-27 20:19:01 -05:00
Bryan Helmkamp 7c603f834c Minor refactorings 2008-12-27 20:18:55 -05:00
Kieran Pilkington 45f36b8ed9 adding specs for the selenium environment/port settings 2008-12-28 12:52:10 +13:00
Mike Gaffney f864bbde52 fixing typos 2008-12-27 17:48:31 -06:00
Mike Gaffney a954b02b22 adding in failure messages 2008-12-27 17:30:54 -06:00
Mike Gaffney 83fd944ecc removing removed files 2008-12-27 17:24:30 -06:00
Mike Gaffney 449edf4a10 updated from master 2008-12-27 17:22:51 -06:00
Mike Gaffney fbcd509097 added code, working on specs 2008-12-27 16:44:54 -06:00
Kieran Pilkington 2c51d90830 adding configuration option to change seleniums environment and port settings 2008-12-28 11:39:34 +13:00
Bryan Helmkamp 362df8abf0 Fix startup bug when using Webrat::Selenium with Test::Unit 2008-12-27 15:57:01 -05:00
Bryan Helmkamp 2bf3c0aaa3 Ignoring test_apps directory for now 2008-12-27 14:04:35 -05:00
Bryan Helmkamp 0eaad52768 Cleanup the way the tests switch Webrat modes 2008-12-25 23:28:29 -05:00
gaffo 22c7834512 Sets the Webrat mode with Configuration#mode= in the config block 2008-12-25 23:07:10 -05:00
Bryan Helmkamp 6d7fc04f71 Add pending spec for bug in #within that needs fixing 2008-12-25 22:53:23 -05:00
Josh Knowles 89e9ea91e9 Support forwarding headers when following redirects when using the SinatraSession 2008-12-25 18:28:54 -05:00
Josh Knowles d0504d9344 First pass at initial specs for Webrat::SinatraSession 2008-12-25 17:58:56 -05:00
Josh Knowles b88b2b2949 Forward headers during redirects when using the RailsSession. 2008-12-25 16:53:06 -05:00
Bryan Helmkamp bd6f4986fb Specs are only pending on MRI. They pass on JRuby 2008-12-25 12:23:06 -05:00
Bryan Helmkamp 5015122fa9 Use a more liberal regexp to try to pass on all platforms 2008-12-25 12:11:48 -05:00
Bryan Helmkamp 267a66cbc1 Try to fix issue where Mechanize mode leaks into spec run 2008-12-25 12:03:05 -05:00
Bryan Helmkamp 056ed85d98 History 2008-12-25 02:11:19 -05:00
Graham Ashton df2df61267 Ensure that Webrat::MechanizeSession.request_page always uses an absolute URL.
Signed-off-by: Bryan Helmkamp <bryan@brynary.com>
2008-12-25 15:03:42 +08:00
Bryan Helmkamp 3492a91c4e Updating gemspec. Another interim release 2008-12-25 01:58:54 -05:00
Noah Davis 0b9fd99bc0 stripping anchor tags from URIs before passing to rails integration session 2008-12-19 14:32:02 -05:00
Luke Melia 7d63aa1a4d Extracted save_and_open_page related functionality to a module and included it in SeleniumSession as well as the standard webrat session. Also added save_and_open_screengrab method to SeleniumSession. 2008-12-19 00:47:26 -05:00
Luke Melia f3dfa329b5 Allow SeleniumSession's click_button to be called without an argument without blowing up. 2008-12-18 02:48:36 -05:00
Luke Melia 492a301449 For your viewing pleasure... maximize the selenium window at after initializing selenium. 2008-12-18 02:45:10 -05:00
Ross Kaffenberger 567f5ada0e Text treated as regexp for buttons 2008-12-17 18:33:20 -05:00
Bryan Helmkamp a5e6af2fe7 Better inspect output for Webrat elements 2008-12-12 15:43:27 -05:00
gaffo ee86067829 updating per reccomendations 2008-12-09 00:12:09 -06:00
gaffo 24ad539671 merging in current codebase 2008-12-08 23:48:00 -06:00
gaffo 28f2898d63 [#85 state:resolved] closed the ticket out and added history 2008-12-08 23:25:23 -06:00
gaffo 2811a089bc webrat config now does the require 2008-12-08 23:19:44 -06:00
Bryan Helmkamp 2d427ed89e simualte and automate need to be there in SeleniumSession too 2008-12-08 04:02:39 -05:00
Bryan Helmkamp 0d028e92fa Include Webrat::Matchers into IntegrationTest 2008-12-07 16:39:09 -05:00
Bryan Helmkamp f53e415076 include Webrat::Selenium::Matchers into Webrat::Selenium::Rails::World 2008-12-07 14:02:06 -05:00
Bryan Helmkamp 0e9f4731bb Adding webrat.simulate and webrat.automate for using the same step mathers in multiple modes 2008-12-03 22:23:13 -05:00
Bryan Helmkamp 881d9f388d Adding have_xpath matcher for Selenium 2008-12-02 22:13:13 -05:00
Bryan Helmkamp 0888c683a3 Added auto-waiting #contain and #have_selector matchers for Selenium 2008-12-02 21:55:09 -05:00
Bryan Helmkamp 0fb3ed6b11 Add docs for Webrat::Selenium 2008-12-02 20:02:08 -05:00
Bryan Helmkamp d1f275734b History 2008-12-02 01:04:17 -05:00
Bryan Helmkamp 5cf23cbda3 Detect if the document is XML or HTML using the Content-Type when in Rails mode 2008-12-02 01:03:38 -05:00
Bryan Helmkamp a205b6fa44 Converting some CSS selectors to XPath 2008-12-02 00:16:15 -05:00
Bryan Helmkamp e88772021b More Webrat implicit waiting. Only load Webrat selectors once per run, not per test 2008-12-01 22:04:24 -05:00
Bryan Helmkamp d8e205cad0 Adding wait_for_element before Webrat actions 2008-12-01 21:15:23 -05:00
Bryan Helmkamp 26a08e69ae Correcting include of Webrat::Methods in Selenium mode 2008-12-01 20:57:57 -05:00
Bryan Helmkamp 53efcc6185 Removing Prototype-specific waits 2008-12-01 20:37:18 -05:00
Bryan Helmkamp 33cfb1cd6a Removing definition of webrat_session method out of the loop 2008-12-01 20:33:01 -05:00
Bryan Helmkamp c86931b401 History 2008-12-01 20:32:06 -05:00
Bryan Helmkamp 2a4959e7f6 Expose #selenium method for direct access to selenium object 2008-12-01 20:28:48 -05:00
Bryan Helmkamp 0de031c93a Check nokogiri gem version before requiring nokogiri
Gives better error messages is using an old nokogiri version
2008-12-01 10:28:02 -05:00
Bryan Helmkamp beb4f976f1 Updating gemspec 2008-11-30 23:45:45 -05:00
Bryan Helmkamp fb2bba23be Removing init.rb auto-require of webrat/rails 2008-11-30 20:37:34 -05:00
Bryan Helmkamp d576a72120 Expose select_option through Webrat::Methods. Minor refactorings 2008-11-30 20:35:08 -05:00
Bryan Helmkamp f5ed57e042 Docs 2008-11-30 20:09:41 -05:00
Bryan Helmkamp 52aa8e2bba Add nokogiri install note to README 2008-11-30 15:54:48 -05:00
Bryan Helmkamp 260ef1ae4e Use FieldNamedLocator in form 2008-11-30 15:51:44 -05:00
Bryan Helmkamp 522bb3272f Initialize locators with a session and a dom instead of a scope 2008-11-30 15:47:31 -05:00
Bryan Helmkamp 9ace546766 Removing more dead methods 2008-11-30 15:39:03 -05:00
Bryan Helmkamp c05c0f6c73 Adding FormLocator. Removing some dead methods 2008-11-30 15:24:50 -05:00
Bryan Helmkamp 0eee6d75e4 Updating SelectOptionLocator to use elements 2008-11-30 15:15:50 -05:00
Bryan Helmkamp ac4feb3b7e Working on SelectOptionLocator 2008-11-30 15:09:54 -05:00
Bryan Helmkamp e72bba29c7 Switching FieldLabeledLocator to use elements 2008-11-30 14:59:33 -05:00
Bryan Helmkamp 28bd5f2533 Load field labels instead of creating new ones 2008-11-30 14:52:52 -05:00
Bryan Helmkamp de2ba2caf8 Ditching preloading of Webrat::Elements 2008-11-30 14:48:32 -05:00
Bryan Helmkamp d48a0fcb15 Refactoring node location 2008-11-30 14:46:52 -05:00
Bryan Helmkamp 53539eda09 Moving around XML code 2008-11-30 01:38:55 -05:00
Bryan Helmkamp f3ff8d4ad2 Refactoring SelectOption creation 2008-11-30 01:29:58 -05:00
Bryan Helmkamp 1e7e977ec4 Moving #path method up to Webrat::Element 2008-11-30 01:27:24 -05:00
Bryan Helmkamp 830b459482 SelectOption is a Webrat::Element too 2008-11-30 01:26:07 -05:00
Bryan Helmkamp c84e5335b5 Moving element files to webrat/core/elements 2008-11-30 01:20:31 -05:00
Bryan Helmkamp 3fd91e34be Extracting Webrat::Element superclass and refactoring element creation 2008-11-30 01:18:36 -05:00
Bryan Helmkamp 4594a39327 Load fields and labels directly from the scope 2008-11-30 00:47:49 -05:00
Bryan Helmkamp 40e0272dff Initialize Labels with a session refrence 2008-11-30 00:38:05 -05:00
Bryan Helmkamp 9e743ea3e2 Stop initializing Fields with references to the Form. They can find it by walking the DOM 2008-11-30 00:35:32 -05:00
Bryan Helmkamp 565e5d221d Add a couple failing specs for select behavior that needs fixing 2008-11-30 00:19:16 -05:00
Bryan Helmkamp 53979cbb52 Working on FieldLabeled locator 2008-11-30 00:12:46 -05:00
Bryan Helmkamp 27626ea389 Refactoring label locating to use elements 2008-11-29 23:59:26 -05:00
Bryan Helmkamp 67dd6d7c58 Moving requires 2008-11-29 23:22:22 -05:00
Bryan Helmkamp 87a4ff91ca Adding Locator#locate! method for error raising 2008-11-29 23:20:36 -05:00
Bryan Helmkamp 53ba0cc691 Extract FieldLocator 2008-11-29 23:11:16 -05:00
Bryan Helmkamp f843ac2ae3 Moving locator methods 2008-11-29 23:08:23 -05:00
Bryan Helmkamp 1647d6ec1e Locator refactoring 2008-11-29 23:03:17 -05:00
Bryan Helmkamp 4ae94af45c Extract LabelLocator 2008-11-29 13:20:18 -05:00
Bryan Helmkamp f6a9bed41e Extract FieldLabeledLocator 2008-11-29 13:02:05 -05:00
Bryan Helmkamp 1723157528 Extracting SelectOptionLocator 2008-11-29 12:55:57 -05:00
Bryan Helmkamp a472bbfbde Namespace locators in Webrat::Locators 2008-11-29 02:00:57 -05:00
Bryan Helmkamp d7eec20950 Extract FieldNamedLocator object 2008-11-29 01:58:27 -05:00
Bryan Helmkamp eb95f6cf09 Refactoring locators 2008-11-29 01:54:49 -05:00
Bryan Helmkamp 04959ae457 Extract FieldByIdLocator object 2008-11-29 01:51:18 -05:00
Bryan Helmkamp 9e030a1b05 Extracting AreaLocator object 2008-11-29 01:48:16 -05:00
Bryan Helmkamp 2e69cb1911 Removing comments 2008-11-29 01:45:03 -05:00
Bryan Helmkamp 5b8a15bae7 Using elements to locate links 2008-11-29 01:44:20 -05:00
Bryan Helmkamp 9254397807 Extracting LinkLocator object 2008-11-29 01:33:55 -05:00
Bryan Helmkamp 0b6d9c28ea Extracting ButtonLocator object 2008-11-29 01:30:23 -05:00
Bryan Helmkamp e5fb990cda Minor cleanups to locators 2008-11-29 01:19:59 -05:00
Bryan Helmkamp 4a63c9bfd1 Switching field_named locator to use elements 2008-11-29 01:14:49 -05:00
Bryan Helmkamp 4736c4cb1a Adding Field.xpath_search method with the XPath to all Webrat fields 2008-11-29 01:12:07 -05:00
Bryan Helmkamp e0488cd8e4 Looking up Fields using Session#elements hash 2008-11-29 01:08:58 -05:00
Bryan Helmkamp 8e864f7e0d Extract Session#reset method 2008-11-29 01:05:19 -05:00
Bryan Helmkamp 154c83eced Store references to Areas in a Session#elements hash 2008-11-29 01:00:18 -05:00
Bryan Helmkamp 857625840f Adding Webrat::XML.xpath_to method 2008-11-29 00:49:00 -05:00
Bryan Helmkamp 6316faae44 Changing Field creation to use XPath 2008-11-29 00:43:24 -05:00
Bryan Helmkamp 3134d1ce73 Add pending spec for not unencoding entities in textarea default values 2008-11-29 00:21:49 -05:00
Bryan Helmkamp f032a8de73 Refactoring CSS searching for building Links, Areas and Forms 2008-11-29 00:11:40 -05:00
Bryan Helmkamp f2758c5d81 Search for areas using the DOM 2008-11-28 19:52:34 -05:00
Bryan Helmkamp 0b1dfbe0a2 Search for buttons using DOM 2008-11-28 18:30:38 -05:00
Bryan Helmkamp ca0642e35c Updating field_with_id to search DOM elements 2008-11-28 18:14:42 -05:00
Bryan Helmkamp 3dce02483b Bump Nokogiri dependency to 1.0.6 2008-11-28 15:13:57 -05:00
Bryan Helmkamp 24923a610d Include the Selenium server jar file in the gem (Bryan Helmkamp, Ben Schwarz) 2008-11-28 15:12:54 -05:00
Bryan Helmkamp ff2dd5de61 Adding require and switching to class_eval 2008-11-28 14:41:17 -05:00
Bryan Helmkamp 97bb64f4f9 Add "rake spec_deps" task to test specs for dependency issues and correct some issues 2008-11-28 03:11:19 -05:00
Bryan Helmkamp ba0e50104b Parse with nokogiri when running the specs on MRI 2008-11-28 03:04:10 -05:00
Bryan Helmkamp 555e24394a Adding "rake precommit" task for running specs against both MRI and JRuby 2008-11-28 03:03:23 -05:00
Bryan Helmkamp 17808cbfb4 Add guilt-inducing pending specs for the set_hidden_field and submit_form methods 2008-11-28 03:02:07 -05:00
Bryan Helmkamp 0619159bec Adding lots of History entries that were missing for work since the last release 2008-11-28 03:01:28 -05:00
Bryan Helmkamp 87211f260d Use REXML and Hpricot together when Nokogiri is not available
This gets us the ability to use XPath consistently, as well as Hpricot's
forgiving parser, when using JRuby
2008-11-28 02:02:17 -05:00
Bryan Helmkamp 18e65bfa44 Cleaning up some more specs 2008-11-28 00:55:45 -05:00
Bryan Helmkamp 31aa659a67 Ensure all example HTML is wrapped in <html> tags 2008-11-28 00:34:35 -05:00
Bryan Helmkamp 3744009dd2 Only run Nokogiri spec when parsing with nokogiri 2008-11-28 00:14:36 -05:00
Bryan Helmkamp 334108015f Abstracting access to inner_html and inner_text to Webrat::XML methods 2008-11-28 00:12:21 -05:00
Bryan Helmkamp 9a344fdc2b Converting usages of element attributes to use a Webrat::XML method 2008-11-27 00:57:10 -05:00
Bryan Helmkamp 7ef8fdf7ba Processing CSS searches as XPath 2008-11-27 00:40:18 -05:00
Bryan Helmkamp 56dc8147f2 Unifying on more usage of css_search method 2008-11-27 00:36:07 -05:00
Bryan Helmkamp e7ddb4bdd1 Extracting hpricot_document method 2008-11-27 00:33:11 -05:00
Bryan Helmkamp b1ef30c71d Removing empty file 2008-11-27 00:29:47 -05:00
Bryan Helmkamp 226ab89a1a Fixing up XHTML in some specs 2008-11-27 00:29:20 -05:00
Bryan Helmkamp 1d5ec1aff9 Un-pending spec that now works 2008-11-27 00:27:13 -05:00
Bryan Helmkamp 8a4a7a328f Revert "Changing field_named and field_with_id to use XPath"
This reverts commit 4a6c6fb2fc.

Conflicts:

	lib/webrat/core/form.rb
2008-11-26 21:37:56 -05:00
Bryan Helmkamp 8770ccb563 Fixing another bug in detecting fields via XPath 2008-11-26 20:47:50 -05:00
Bryan Helmkamp 4f530cfa29 Extending ActionController::IntegrationTest instead of ActionController::Integration::Session fixes error with Webrat's select method 2008-11-26 14:26:10 -05:00
Bryan Helmkamp 01fcd0dea1 Making Webrat's usage of the #path Nokogiri method work with Hpricot too 2008-11-26 14:25:42 -05:00
Bryan Helmkamp 54de30032e Updating Webrat require in init.rb 2008-11-26 14:24:58 -05:00
Bryan Helmkamp 557d9711e5 Correcting specdoc 2008-11-26 13:47:36 -05:00
Bryan Helmkamp aecd70dd15 Add pending spec for bug. Webrat needs to escape quotes in XPath 2008-11-26 08:32:22 -05:00
Bryan Helmkamp f7addd1d38 Add IRC channel to README 2008-11-25 14:07:42 -05:00
Bryan Helmkamp 5f405ebbdc Update link to RDoc in README 2008-11-25 10:15:39 -05:00
Bryan Helmkamp e822535b6e More minor RDoc tweaks 2008-11-25 01:34:34 -05:00
Bryan Helmkamp 2eefcf5060 Adding .document RDoc config file 2008-11-25 01:04:26 -05:00
Bryan Helmkamp 6119a8d08f Exclude .js files from RDoc 2008-11-25 00:06:28 -05:00
Bryan Helmkamp 491ceb7e5b Deprecating old style Selenium methods 2008-11-25 00:03:16 -05:00
Bryan Helmkamp 9b1503508b Deprecating old style methods 2008-11-24 23:55:39 -05:00
Bryan Helmkamp 2c26bc8dab Updating and improve README (Bryan Helmkamp / Mike Gaffney) 2008-11-24 23:30:10 -05:00
Bryan Helmkamp 4a6c6fb2fc Changing field_named and field_with_id to use XPath 2008-11-24 21:59:56 -05:00
Bryan Helmkamp 6a096dd434 Adding gemspec. Hopfully gem will build on GitHub now 2008-11-24 20:34:10 -05:00
Bryan Helmkamp 5fd88ba4de Bumping revision for pre-release gem 2008-11-24 20:29:58 -05:00
Bryan Helmkamp 2dd884554f Dropping RDoc formatting to make things look prettier on GitHub 2008-11-24 20:27:52 -05:00
Bryan Helmkamp f19527627b More links for the README 2008-11-24 20:26:37 -05:00
Bryan Helmkamp 03d7c71ef9 Updating docs rake task 2008-11-24 20:10:27 -05:00
Bryan Helmkamp 3b8fc5551f RDoc tweaks 2008-11-24 20:03:32 -05:00
Bryan Helmkamp 5502948417 Starting on field_with_xpath implementation 2008-11-24 14:15:28 -05:00
Bryan Helmkamp fe8a8cf435 Rename spec files to reflect method names 2008-11-24 02:33:07 -05:00
Bryan Helmkamp da68aa8bce Cleaning up Selenium support. Mongrel and Selenium servers start/shutdown automatically 2008-11-23 19:46:37 -05:00
Bryan Helmkamp e6cb40b66e Adding methods to start and stop the selenium server java process 2008-11-23 15:44:49 -05:00
Bryan Helmkamp f6ce5bbfb1 Using configuration in Webrat instead of defined? checks 2008-11-23 14:59:07 -05:00
Bryan Helmkamp 1017fdfba7 parse_with_nokogiri default to true on MRI and false on JRuby 2008-11-23 14:49:05 -05:00
Bryan Helmkamp 302f0dc1c6 Add a configuration option for parse_with_nokogiri 2008-11-23 14:44:13 -05:00
Bryan Helmkamp 0d205e382b Don't need a default mode 2008-11-23 14:40:19 -05:00
Bryan Helmkamp 1fb3fd07d4 Using Webrat mode to determine which logger to use 2008-11-23 14:13:34 -05:00
Bryan Helmkamp 59560a043b Removing Webrat.root method 2008-11-23 14:13:29 -05:00
Bryan Helmkamp 48e43a257c Always raise Webrat::WebratErrors (or a subclass), not RuntimeErrors 2008-11-23 14:08:34 -05:00
Bryan Helmkamp db0488c0e2 Updating usages of "selects" methods to "select" 2008-11-23 14:05:04 -05:00
Bryan Helmkamp f03905e6b6 Use Webrat::Methods in specs 2008-11-23 00:48:42 -05:00
Bryan Helmkamp adf68c2f8f Change Webrat Rails integration to use the Webrat::Methods module 2008-11-22 23:49:12 -05:00
Bryan Helmkamp a8e02a6b6e Switch to using Nokogiri.parse for XML/XHTML autodetection [#66 state:resolved] 2008-11-22 16:46:03 -05:00
Bryan Helmkamp bb5eac701d Add pending spec for XML bug 2008-11-20 16:15:42 -05:00
Luke Melia 9b5ffacecc Switch to using selenium-client gem and vendor selenium-server.jar (not used directly from webrat yet) 2008-11-20 16:07:18 -05:00
Luke Melia f262e338bf Added pending spec for clicks_link not matching inner_html. Fix will be involved and likely breaking, because clicks_link does explicitly match inner_html today. However, we think the spec makes clear why it shouldn't. Luke Melia / Noah Davis 2008-11-20 15:23:31 -05:00
Bryan Helmkamp ba3e29d2a3 Changing rake default from verify_rcov to spec 2008-11-19 15:59:24 -05:00
Bryan Helmkamp f1b4486594 Moving requiring of Nokogiri/Hpricot/REXML to a method 2008-11-19 15:52:56 -05:00
Bryan Helmkamp ec8bc82c24 Adding response method to MechanizeSession 2008-11-18 22:56:35 -05:00
Bryan Helmkamp 0dd7ea2ae0 Remove references to deleted TODO.txt 2008-11-18 22:17:11 -05:00
Bryan Helmkamp 22d5b91dd4 Add spec:jruby task for running spec suite with jruby 2008-11-18 21:09:48 -05:00
Bryan Helmkamp 10d5d7695f Raise Webrat::NotFoundErrors instead of RuntimeErrors to make error catching easier 2008-11-18 20:55:55 -05:00
Bryan Helmkamp df9d8179c0 Field#to_param should return a hash when Merb is not defined for Mechanize support [#62 state:resolved] 2008-11-18 20:48:12 -05:00
Bryan Helmkamp 5a9c048dfb Adding example for clicking a link with an amperstand 2008-11-18 20:41:14 -05:00
moro dc52f07a9f Link#matches_text?() use @element.text as text
It decodes character references.
Userful for multibyte languages(eg. Japanese).

And also uses @element.inner_html to match with HTML (eg.image link)
2008-11-18 20:37:35 -05:00
Josh Knowles 95604d6320 Caching the config should actually cache the config 2008-11-18 20:32:27 -05:00
Bryan Helmkamp 5ee4357cd6 Add set_hidden_field and submit_form methods ND/BH 2008-11-17 14:21:16 -05:00
Bryan Helmkamp 3abaa924cc Changing requiring of nokogiri to work on jruby 2008-11-17 00:05:57 -05:00
Bryan Helmkamp 1bdead1655 Bug fix for hash merging Mashes 2008-11-16 23:21:29 -05:00
Drew Colthorp 83f3ab468d fixed bug where webrat would lose complex parameters (like foo[bar[baz]][]) in merb due to not correctly merging Mashes. 2008-11-16 23:15:50 -05:00
Bryan Helmkamp 5249826cb7 Working on running specs in separate processes 2008-11-16 23:04:34 -05:00
Bryan Helmkamp 3d467f3c11 Revert "adding html unit spike" which was inadvertantly merged in
This reverts commit 0800f79428.
2008-11-16 21:35:11 -05:00
Bryan Helmkamp 50762b6f5a Cleaning up some requires to get rid of double-includes during spec runs 2008-11-16 21:25:29 -05:00
Bryan Helmkamp f2f8bae190 Removing :suffixes and :suffix_convention options from selects_date and selects_time methods 2008-11-16 19:29:13 -05:00
Bryan Helmkamp 31cc6b75da Collapsing Webrat::Core module. Moving configuration methods to configuration.rb 2008-11-16 18:58:24 -05:00
Bryan Helmkamp 9f8a88d649 Merge commit 'gaffo/webrat_config' 2008-11-16 18:51:42 -05:00
Bryan Helmkamp 0fa62eb903 Removing TODO (captured in Lighthouse tickets now). See http://webrat.lighthouseapp.com/ 2008-11-16 18:43:58 -05:00
Bryan Helmkamp fe16731370 Merge commit 'bmabey/master' 2008-11-15 19:39:03 -05:00
Ben Mabey a381cbf17e helpful error message for missing option values, closes #40 2008-11-15 19:32:47 -05:00
Ben Mabey d0d9ca8787 removing extra require 2008-11-15 19:32:39 -05:00
Ben Mabey b8d413a14b removing extra require 2008-11-15 14:58:59 -07:00
Ben Mabey 4dd1c4b62d helpful error message for missing option values, closes #40 2008-11-15 14:57:57 -07:00
Ben Mabey 6cd76fa08e selects_time, selects_date, and selects_datetime added to API. Closes #36. 2008-11-15 14:06:04 -07:00
Ben Mabey 0dffbec8f4 Merge branch 'brynary/master' 2008-11-15 10:47:58 -07:00
gaffo 1a69a9a34b moved config down to root, kept config object 2008-11-14 18:50:45 -06:00
gaffo 19353b507b Revert "[#33 state:resolved] refactored to move the config down to Webrat::Core as it seemed nicer"
This reverts commit 58cbf49119.
2008-11-14 18:32:05 -06:00
Bryan Helmkamp 3e70fd24eb Make #value on Field readable 2008-11-14 11:41:56 -05:00
Ryan Briones 2603ad405b allow mechanize session to pass through basic auth 2008-11-14 11:23:50 -05:00
gaffo 58cbf49119 [#33 state:resolved] refactored to move the config down to Webrat::Core as it seemed nicer 2008-11-14 00:11:29 -06:00
Luke Melia 82b1553719 Added RadioField#checked? to indicated whether or not a radio button is checked. 2008-11-14 01:09:18 -05:00
gaffo 3fbf5ae930 merged in current webrat master 2008-11-14 00:01:27 -06:00
gaffo 7460c85655 [#33 state:resolved] added a configuration object that is configurable by a block 2008-11-13 23:58:52 -06:00
Bryan Helmkamp f29cb53239 Merge commit 'gaffo/master'
Conflicts:
	.gitignore
	History.txt
	lib/webrat/core/scope.rb
	spec/webrat/rails/rails_session_spec.rb
2008-11-14 00:04:53 -05:00
Bryan Helmkamp 1cdf95851b Merge commit 'gaffo/multi_os_for_open_in_browser' 2008-11-13 23:53:36 -05:00
gaffo e1444d58ef added support for windows and cygwin 2008-11-13 22:33:33 -06:00
Bryan Helmkamp 74dce87c3e Merge commit 'lawrencepit/banana'
Conflicts:
	spec/api/click_link_spec.rb
2008-11-13 22:43:17 -05:00
Bryan Helmkamp e8c9f04a19 Merge commit 'jrun/master'
Conflicts:
	.gitignore
2008-11-13 22:40:05 -05:00
Nando 5cbd5c4a12 Ignore .svn 2008-11-13 22:33:04 -05:00
Nando 92b4814392 Added key_down and key_up wrapper in Selenium session 2008-11-13 22:31:59 -05:00
Nando db81a97e42 Added fire_event wrapper in Selenium sessions 2008-11-13 22:29:17 -05:00
Bryan Helmkamp 6ccb8a6c3a Flip compound conditional to if 2008-11-13 22:20:39 -05:00
Nando ad89560707 Multiple test environments support 2008-11-13 21:47:37 -05:00
Jeremy Burks b3ad31ee95 spec.opts 2008-11-13 21:28:28 -05:00
Bryan Helmkamp 902316c559 Merge commit 'cclow/master' 2008-11-13 21:23:04 -05:00
Low Chin Chau 9b3702a7d2 fixed webrat/core/methods to recognise for click link within 2008-11-13 21:19:59 -05:00
Nando f1df102428 Fixed README filename 2008-11-13 21:18:22 -05:00
Bryan Helmkamp 0081ea2391 Merge commit 'dchelimsky/master' 2008-11-13 21:14:04 -05:00
Bryan Helmkamp 0a2fc91cbb Merge commit 'mfilej/master' 2008-11-13 21:11:50 -05:00
Ben Mabey b8a87e3143 Merge branch 'brynary/master' 2008-11-13 15:05:56 -07:00
Miha Filej 0f7a277c57 Make Webrat::Label#text strip out newlines 2008-11-13 15:00:24 +01:00
David Chelimsky 032a016564 add simple support for accessing have_tag, have_selector and have_xpath matchers from rspec proper 2008-11-12 12:38:12 -06:00
Low Chin Chau e51238e471 fixed webrat/core/methods to recognise for click link within 2008-11-12 14:50:50 +08:00
Low Chin Chau 57d2bd2b90 fixed webrat/core/methods to recognise singular verbs 2008-11-12 14:48:18 +08:00
Jeremy Burks a570d40f70 core expects a response so mechanize got one 2008-11-11 20:08:17 -06:00
Jeremy Burks 92fde1d8de Merge branch 'master' of git://github.com/brynary/webrat into brynary/master
Conflicts:
	Manifest.txt
	lib/webrat/mechanize/mechanize_session.rb
2008-11-11 19:47:49 -06:00
Jeremy Burks 255788e14b spec.opts 2008-11-11 19:38:30 -06:00
Bryan Helmkamp b4bdeb5319 Fall back on Hpricot when Nokogiri isn't available (eg. JRuby) 2008-11-11 00:28:38 -05:00
Bryan Helmkamp 82c6be380e Raise Webrat::PageLoadError when a failure occurs so that application exceptions can be more accurately tested (Ryan Briones) 2008-11-10 14:15:40 -05:00
Bryan Helmkamp 59704da270 Extracting some rexml code into a module 2008-11-09 20:49:55 -05:00
Jeremy Burks 7dfd59c29c the mechanize session must specially handle params
{:user => {:name => "Nancy"}}
now becomes
{"user[name]" => "Nancy"}
2008-11-08 08:46:14 -06:00
Jeremy Burks d039c9590f ignore the log dir 2008-11-08 08:45:51 -06:00
Lawrence Pit 98d52176ad fix following fully qualified local links 2008-11-05 14:20:47 +11:00
Jeremy Burks 5623643b53 exposed the mechanize page 2008-11-03 20:44:33 -06:00
gaffo 7b254be895 [#25 state:closed] updated history 2008-10-28 21:34:06 -05:00
gaffo 397dec1436 added id support on clicks_link, added tests for matches_text? and matches_id? into link spec 2008-10-28 21:32:55 -05:00
gaffo 067bc791c5 added tests for substrings 2008-10-28 21:13:54 -05:00
gaffo 275829d382 [#25 state:open] Added tests to create matches_id? function in link 2008-10-28 21:09:23 -05:00
gaffo 8ce99ccf9a Merge branch 'master' of git://github.com/brynary/webrat into lh_25_click_link_by_id 2008-10-28 20:23:55 -05:00
Jeremy Burks 40c6b6ed44 "fixed" MechanizeSession, Session expects get and post to have 3 arguments 2008-10-27 22:01:48 -05:00
Jeremy Burks 71adad4ada the manifest was missing core/mime.rb 2008-10-27 22:01:27 -05:00
Jeremy Burks 5efa47aa53 fixed requires and manifest 2008-10-27 21:58:21 -05:00
Jeremy Burks d03ed0238c Merge branch 'master' of git@github.com:jrun/webrat 2008-10-27 21:29:28 -05:00
Jeremy Burks 0b17495446 move merb/param_parser to core so it can be used for other sessions other than merb (i.e. mechanize) 2008-10-27 21:29:22 -05:00
gaffo 9b72542b95 hi 2008-10-22 00:02:04 -05:00
mike.gaffney f3d508b817 added another stipulation to the https get test on rails session. Added a test for the link object with 2 simple tests. 2nd was done while looking for a bug 2008-10-21 23:55:58 -05:00
Ben Mabey 0800f79428 adding html unit spike 2008-09-15 12:03:42 -06:00
246 changed files with 10638 additions and 3691 deletions

4
.document Normal file
View File

@ -0,0 +1,4 @@
README.rdoc
lib/**/*.rb
History.txt
MIT-LICENSE.txt

12
.gitignore vendored
View File

@ -4,3 +4,15 @@ pkg
doc
ri
email.txt
.svn
log
.project
.loadpath
*.swp
results
test_apps
*.tmproj
*.log
*.pid
bin
vendor/gems

13
Gemfile Normal file
View File

@ -0,0 +1,13 @@
gem "rake", "0.8.7"
gem "rspec", "1.2.9"
gem "diff-lcs", "1.1.2"
gem "rack", "1.0.1"
gem "nokogiri", "1.4.0"
gem "merb-core", "1.0.15"
gem "selenium-client", "1.2.17"
gem "mechanize", "0.9.3"
gem "rails", "2.3.4"
gem "launchy", "0.3.3"
gem "rack-test", "0.5.2"
gem "sinatra", "0.9.4"
gem "mongrel", "1.1.5"

View File

@ -1,44 +1,358 @@
== 0.7.1 / 2010-04-26
* Minor enhancements
* Move verbose selenium output that can clutter build output behind setting
* Added application_port_for_selenium to webrat configuration. The use case is when you want to test through a web server sitting in front of your application server. (Luke Melia)
* New webrat configuration option selenium_firefox_profile which is passed to selenium server
* Allow submit_form to select by CSS too (Damian Janowski)
* Bug fixes
* Fix that current_url wasn't reflecting redirects in Mechanize [#332] (Emrys Ingersoll)
* Fix attach_file with nested params [#341] (Álvaro Gil)
* Fix that a 304 was considered a redirect (Larry Marburger)
* Fix selection of LABEL elements in Selenium mode under IE [#317] (Damian Janowski, Noah Davis)
* Fix have_xpath not matching negative expectation in the block [#182] (Luismi Cavallé)
== 0.7.0 / 2010-01-17
* Major enhancements
* Upgrade bundled Selenium server JAR to 2.0a1 (Henry Poydar and Jake Scruggs)
* Minor enhancements
* Save and open page directory specified via configuration, defaults to tmp dir otherwise current dir (Noah Davis)
* Bug fixes
* Added missing dependency "rack-test" to gemspec (LH #339) (Noah Davis)
* Removed save_and_open_page's rewriting of static asset paths before saving (was not actually working) (Noah Davis)
* Make "should contain" ignore extra whitespace when doing string comparisons (Noah Davis)
* Make selenium matchers handle negative match more consistently with positive match (Luke Melia)
== 0.6.0 / 2009-11-28
REMOVED: Support for Hpricot + REXML as an alternative to Nokogiri.
Hpricot and REXML were difficult to work with, REXML is terribly slow,
and Nokogiri is recommended even by the author of Hpricot (_why). Now
that Nokogiri works on JRuby, Webrat is going to use it as its sole
XML backend.
CHANGED: Due to a reorganization, if you're currently requiring "webrat/rspec-rails",
please change your code to require "webrat/integrations/rspec-rails"
* Minor enhancements
* Support Rails 2.3.4 JavaScript form authenticity tokens in simulated mode (Jonathan Weiss)
* When a timeout occurs in wait_for, include the HTML from Selenium in the exception
* Update the Merb support to be based directly on Rack (Simon Rozet)
* Support multiple select fields (Kieran P)
* When locating select options, always match against text, not HTML
* Bug fixes
* Remove newlines from HTTP Basic authentication credentials (Michael Klett)
* Require nokogiri form rspec-rails.rb (David Chelimsky)
* Fix logger issue when running inside Cucumber (Damian Janowski)
* Fix various issues related to submitting values with HTML entities (Kieran P)
* Call #to_i on the :count option in matchers (Michael Christenson II)
* Fix bug where multiline param values were getting truncated
== 0.5.3 / 2009-08-27
* Minor enhancements
* Remove unnecessary requires which are to the wrong paths on Edge Rails
== 0.5.1 / 2009-08-18
* Minor enhancements
* Base Webrat::MIME on Rack::Mime (Simon Rozet)
* Support file uploads in Rack mode (Simon Rozet)
* Bug fixes
* Fix bug in Webrat::Methods preventing Selenium mode from working [#277]
== 0.5.0 / 2009-08-12
* Major enhancements
* Depreacate :rack_test and :sinatra in favor of :rack, which uses Rack::Test (Simon Rozet)
* Minor enhancements
* Don't require rubygems at runtime (Simon Rozet)
== 0.4.5 / 2009-08-10
* Major enhancements
* Ruby 1.9 compatibility (Michael Fellinger, Jakub Kuźma)
* Improve performance (~2x) on JRuby by supporting Nokogiri
* Added support for external app servers in selenium mode (basically don't start one) (Mike Gaffney)
* Added support for uploading files for Merb (Ryan Carver)
* Minor enhancements
* Upgrade to selenium-client to 1.2.16 (Brian Landau)
* Upgrade selenium-server.jar to 1.0.1 (Brian Landau)
* Make redirect detection work in the face of rational maths (like when ruby-units is active) (Piers Cawley)
* Use Launchy to handle opening pages in the browser with cross-platform compatibility (Bryan Helmkamp)
* Added support for field_labeled_locators ending in non word characters
lh 148 (Zach Dennis)
* Filled in tests on click link lh 195 (diabolo)
* Added current_url to selenium session lh 215 (Luke Amdor)
* Added silence spec to selenium lh 238 (Martin Gamsjaeger aka snusnu)
* Added ability to configure the browser startup timeout for selenium lh 242 (Mike Gaffney, Mark Dodwell)
* Added delegation for field_named lh194 (pivotal labs)
* Added fix to keep from escaping field values in mechanize mode lh256 (jish)
* Adding fixes for click button/link and made the integration specs pass for the same in selenium lh254 (Ldiehl, Matthias Marschall)
* Adding clicking link by id in selenium mode lh221 (larrytheliquid)
* Adding fix for have_selector and have_xpath in descendent blocks lh234 (Thomas Jack)
* Adding fix for fields with labels with special characters (Thomas Jack, Mike Gaffney, Bryan Hemlkamp)
* Deprecated current_page lh50 (Mike Gaffney)
* Fixed issue with redirects and multiple hosts lh168 (Mutwin Kraus)
* Bug fixes
* Wait for application servers socket on 0.0.0.0 instead of the application_address
* Translate CSS and image paths with single quotes in save_and_open_page (Erin Staniland)
== 0.4.4 / 2009-04-06
* Major enhancements
* Make selenium process management code more robust and informative
* Minor enhancements
* Add support for Rails javascript post links (Mark Menard)
* Upgrade selenium-client dependency to 1.2.14, and update for new waiting
API (Balint Erdi)
* Change default app environment from "selenium" to "test"
* Bug fixes
* Don't create a new instance of WWW::Mechanize for each request
(Mark Menard)
* Select fields with duplicate selected options sent an incorrect value (Noah Davis)
== 0.4.3 / 2009-03-17
* Minor enhancements
* Support Rails 2.3. Use Rack::Utils to parse params (Matthew Ford)
* Support for "modular" Sinatra app style (Simon Rozet)
* Initial Merb and Sinatra compatibility for Selenium mode (Corey Donohoe)
* When faced with a label with no for attribute, that contains a hidden field
and another field, as can be the case in Rails 2.3's checkbox view,
webrat now locates the non-hidden field. (Luke Melia)
* Add application_framework config for Selenium mode to determine how to
start and stop the app server (Corey Donohoe)
* Bug fixes
* Fix following of absolute redirect URL in Sinatra (Simon Rozet)
== 0.4.2 / 2009-02-24
* Major enhancements
* Significant improvements to have_selector. It now supports specifying
attributes in a hash and :count and :content options. See
have_selector_spec.rb for more.
* Add the same functionality mentioned above to have_xpath
* Minor enhancements
* Squeeze extra whitespace out of failures messages from contain
matcher
* Detect infinite redirects and raise a Webrat::InfiniteRedirectError
(Daniel Lucraft)
* Bug fixes
* Properly quote single and double quotes strings in XPath
* Fix warning caused by Nokogiri deprecating CSS::Parser.parse
(Aaron Patterson)
* Accept do/end blocks in matchers. [#157] (Peter Jaros)
* Quote --chdir option to mongrel_rails to support RAILS_ROOTs with spaces
(T.J. VanSlyke)
== 0.4.1 / 2009-01-31
* Minor enhancements
* Support Sinatra 0.9 (Harry Vangberg)
* Update query param parsing to work with latest Edge Rails
* Added #redirected_to method to easily check where an external redirect was
redirected to (Adam Greene)
* Recognize input tags with type button (Lena Herrmann)
* Add uncheck method to Selenium mode (Lee Bankewitz)
* Bug fixes
* Make requests to a Rails app using a full URL instead of a relative path. This change
is helpful for Rails apps that use subdomains. (John Hwang and Zach Dennis)
* Follow redirects that are on the same domain but a different subdomain
(Adam Greene)
* rescue from Webrat::TimeoutError in selenium matchers which allows NegativeMatchers
to behave correctly (Noah Davis)
* Switch to using selenium.click instead of .check when checking a checkbox
(Noah Davis)
* Create tmp/pids directory if directory does not exist. (Amos King and Mike Gaffney)
* Setup deprecated writers for the selenium_environment= and selenium_port= config
* Ensure the previous pages params aren't passed through redirect (Daniel Lucraft and
Bryan Helmkamp)
* Labels should only search for fields within the current scope (Kyle Hargraves)
== 0.4.0 / 2009-01-18
* _IMPORTANT_ Breaking change:
* Removed init.rb auto-require of webrat/rails
* Removed auto-require of webrat/rails when requiring webrat when RAILS_ENV is
defined
In your env.rb or test_helper.rb file, ensure you have something like:
require "webrat"
Webrat.configure do |config|
config.mode = :rails
end
* Major enhancements
* Major improvements to Webrat::Selenium (Many contributors listed here)
* Add assert_* methods for using Webrat's matchers w/o RSpec (Mike Gaffney, Amos King)
* Added Webrat.configure method for Webrat configuration [#33] (Mike Gaffney)
* Added select_time, select_date, and select_datetime to API. [#36] (Ben Mabey)
* Use Hpricot and REXML when not parsing with Nokogiri (on JRuby, for example)
* Minor enhancements
* Added Selenium grid configuration and support. (Amos King && Cornel Borcean)
* Support passing an ActiveRecord model to #within when in Rails mode [#68] (Luke Melia)
* Make assert_* matchers in rails mode increment the assertions count [#123] (Amos King)
* Added assert_* matchers to selenium matchers [#110] (Amos King)
* Added assert_contain, assert_not_contain [#86] (Mike Gaffney, Amos King)
* Add configuration options for the Selenium environment and port (Kieran Pilkington)
* Maximize the browser window after initializing Selenium (Luke Melia)
* Better inspect output for Webrat elements
* Sets the Webrat mode with Configuration#mode= in the config block [#85] (Mike Gaffney)
* Detect if the document is XML or HTML using the Content-Type when in Rails mode
* Expose #selenium method for direct access to Selenium client
* Check nokogiri gem version before requiring nokogiri
* Include the Selenium server jar file in the gem (Bryan Helmkamp, Ben Schwarz)
* Added key_down, key_up and fire_event to Selenium session (Fernando Garcia)
* Fix outputing README during Rails plugin install (Fernando Garcia)
* Strip newlines when matching label text (Miha Filej)
* Add simple support for accessing Webrat's matchers from RSpec by requiring
"webrat/rspec-rails" (David Chelimsky)
* Support save_and_open_page in Windows and Cygwin (Mike Gaffney)
* Added RadioField#checked? to indicated whether or not a radio button is checked
(Luke Melia)
* Add spec:jruby rake task for running Webrat's spec suite with JRuby
* Added field_by_xpath to locate a Webrat::Field using arbitrary XPath expressions
* Helpful error message for missing option values [#40] (Ben Mabey)
* Add set_hidden_field method (Noah Davis, Bryan Helmkamp)
* Add submit_form method for submitting a form by ID (Noah Davis, Bryan Helmkamp)
* Switch to using Nokogiri.parse for simple XML/XHTML autodetection [#66]
* Removed Webrat.root method, which seemed to be unused
* Added automatic starting and stopping of the Selenium server and a Mongrel Rails
app server when using webrat/selenium
* Switch to using selenium-client gem and vendor selenium-server.jar (Luke Melia)
* Added gemspec so the gem builds on GitHub now
* Deprecate old style methods (fills_in is deprecated in favor of fill_in, etc.)
* Improvements to the README and RDoc (Bryan Helmkamp, Mike Gaffney)
* Allow clicking links by id and id regexp (Mike Gaffney)
* Raise Webrat::DisabledFieldError when attempting to manipulate a disabled field
* Raise Webrat::NotFoundErrors when an element is not found
* Raise Webrat::PageLoadError when a failure occurs so that application exceptions
can be more accurately tested (Ryan Briones)
* Helpful error message for missing option in select box. [#40] (Ben Mabey)
* Extracted save_and_open page to make it usable in Selenium mode (Luke Melia)
* Added save_and_open_screengrab for Selenium mode (Luke Melia)
* Bug fixes
* field_labeled should disregard labels without matching fields (Kyle Hargraves)
* Fixed bug where Scope was creating a new DOM rather than re-using the existing DOM.
[#105] (Zach Dennis)
* Support Rails > v2.2 by using ActionController::RequestParser for param parsing [#107]
(Marcello Nuccio)
* Raise a Webrat::NotFoundError if the scope passed to #within doesn't exist [#90]
* Match against link _text_ which decodes character references.
Useful for multibyte languages like Japanese (moronatural@gmail.com)
* Fix params hash generation for Mechanize when Merb is not defined [#62]
* Expose some Webrat methods that were missing from the Webrat::Methods module
(Low Chin Chau)
* Allow mechanize session to pass through basic auth (Ryan Briones)
* Improvements to the Mechanize support (Jeremy Burks)
* Fix following fully qualified local links (Lawrence Pit)
* Fixed bug where Webrat would lose complex parameters (like foo[bar[baz]][])
in Merb due to not correctly merging Mashes. (Drew Colthorp)
* Extend Rails' ActionController::IntegrationTest instead of
ActionController::Integration::Session (Fixes using Webrat's #select method and
avoids usage of method_missing)
* Ensure that Webrat::MechanizeSession.request_page always uses an absolute
URL. (Graham Ashton)
* Strip anchor tags from URIs before passing to Rails integration session
(Noah Davis)
* Treat text and regexp when matching Selenium buttons (Ross Kaffenberger)
* Allow SeleniumSession's click_button to be called without an argument without
blowing up (Luke Melia)
== 0.3.4 / 2008-12-29
* 1 Minor enhancement
* Fix compatibility with Nokogiri 1.1.0 on JRuby
* 1 Bug fix
* Correct version for Nokogiri dependency in gem
== 0.3.3 / 2008-12-28
* 1 Minor enhancement
* Fix compatibility with Nokogiri 1.1.0 on MRI
== 0.3.2 / 2008-11-08
* 1 Minor enhancement
* Fixes behavior or have_tag when a block is passed. It passes the matched node(s) to the block for further specs again. (Carl Lerche)
* Fixes behavior or have_tag when a block is passed. It passes the matched node(s)
to the block for further specs again. (Carl Lerche)
== 0.3.1 / 2008-11-07
* 1 Minor enhancement
* Use @_webrat_session instance variable instead of @session for Merb integration to avoid collisions
* Use @_webrat_session instance variable instead of @session for Merb integration
to avoid collisions
== 0.3.0 / 2008-11-07
* Major enhancements
* 4 Major enhancements
* Added Merb support (Gwyn Morfey, Jeremy Burks, Rob Kaufman, Yehuda Katz)
* Added experimental Selenium support (Luke Melia)
* Add have_selector, have_xpath, have_tag and contain matchers from Merb
* Switch from Hpricot to Nokogiri for XML parsing (thanks, Aaron Patterson)
* Minor enhancements
* 37 Minor enhancements
* Added #within for manipulating the current page within a selector scope
* Add support for file fields via #attaches_file method (Rails only at the moment) (Kyle Hargraves)
* Add support for file fields via #attaches_file method (Rails only at the moment)
(Kyle Hargraves)
* Add support for simulating SSL requests (Luke Melia)
* Added #basic_auth(user, pass) to support HTTP Basic Auth (Aslak Hellesøy)
* Added support for Sinatra and Rack (Aslak Hellesøy)
@ -51,33 +365,37 @@
* Allow clicking links by a regular expression
* Add #http_accept for including MIME type HTTP "Accept" headers (Ryan Briones)
* Add #header to support inclusion of custom HTTP headers (Ryan Briones)
* Consider response codes 200-499 as successful enough to not raise a Webrat error (David Leal)
* Add Webrat.root method for cross-framework support (Krzysztof Zylawy)
* Consider response codes 200-499 as successful enough to not raise a Webrat error
(David Leal)
* Add support for clicking areas of an image map (Alex Lang)
* Support relative links, including href="?foo=bar" (Kyle Hargraves)
* Separated Rails-specific code from the Webrat core to make it easier to use Webrat with other environments
* Separated Rails-specific code from the Webrat core to make it easier to use
Webrat with other environments
* Alias visits as visit, clicks_link as click_link, etc. for better readability
* Raise error when trying to interact with a disabled form element (Luke Melia)
* Don't send disabled form elements to the server (Nicholas A. Evans)
* Display response body when the page load is not successful (David Leal)
* CGI escape form field values (Miha Filej)
* Add support for redirect_to :back by sending HTTP_REFERER headers (Hendrik Volkmer)
* Add support for redirect_to :back by sending HTTP_REFERER headers
(Hendrik Volkmer)
* Expose current DOM (as an Hpricot object) as #current_dom
* Add support for disabling JavaScript when clicking a link to enable testing of both JS
and non-JS implementations (Luke Melia and Bryan Helmkamp)
* Add support for disabling JavaScript when clicking a link to enable testing of
both JS and non-JS implementations (Luke Melia and Bryan Helmkamp)
* Support &nbsp's as spaces in matching link text (Luke Melia)
* Support button elements (Nick Sieger)
* Support matching select options by regexp (Kyle Hargraves)
* save_and_open_page rewrites css and image references to provide a friendlier debugging experience (Luke Melia)
* Added support for matching alt attributes in fields (primarly for clicks_button) (Aaron Quint)
* save_and_open_page rewrites css and image references to provide a friendlier
debugging experience (Luke Melia)
* Added support for matching alt attributes in fields (primarly for clicks_button)
(Aaron Quint)
* Support '&amp;' in submitted values (Kyle Hargraves)
* Support clicking links by title (Dan Barry)
* Added missing spec for clicking image buttons (Tim Harper)
* Switched tests to specs, and from Mocha to RSpec's mocking library
* Add support to click_button for IDs (Gwyn Morfey)
* Miscellaneous core refactorings (Jan Suchal)
* Bug fixes
* 8 Bug fixes
* Fix initialization of WWW::Mechanize (Derek Kastner)
* Don't open blank pages in the browser (Kyle Hargraves)
@ -86,8 +404,9 @@
* Fix bug with empty select list option (Kyle Hargraves)
* Fix regression of not sending default values in password fields
* Don't explode if encountering inputs with no type attribute (assume text)
* Fix bug where choosing a radio button in a series with a default submitted the incorrect field value (Luke Melia)
* Fix bug where choosing a radio button in a series with a default submitted the
incorrect field value (Luke Melia)
== 0.2.0 / 2008-04-04
* 4 Major enhancements
@ -97,31 +416,35 @@
* Add basic support for Rails-generated JavaScript link tags
* Add support for checkboxes (Patches from Kyle Hargraves and Jarkko Laine)
* Add support for textarea fields (Sacha Schlegel)
* 8 Minor enhancements
* Added reloads method to reload the page (Kamal Fariz Mahyuddi)
* Prevent making a request if clicking on local anchor link (Kamal Fariz Mahyuddi)
* Added clicks_link_within(selector, link_text), allowing restricting link search
to within a given css selector (Luke Melia)
* Added clicks_link_within(selector, link_text), allowing restricting link search
to within a given css selector (Luke Melia)
* Allow specifying the input name/label when doing a select (David Chelimsky)
* Raise a specific exception if the developer tries to manipulate form elements before loading a page (James Deville)
* Raise a specific exception if the developer tries to manipulate form elements
before loading a page (James Deville)
* Add support for alternate POST, PUT and DELETE link clicking (Kyle Hargraves)
* Change clicks_link to find the shortest matching link (Luke Melia)
* Improve matching for labels in potentially ambiguous cases
* 7 Bug fixes
* Fix incorrect serializing of collection inputs, i.e. name contains [] (Kamal Fariz Mahyuddi)
* Fix incorrect serializing of collection inputs, i.e. name contains []
(Kamal Fariz Mahyuddi)
* Serialize empty text field values just like browsers (Kamal Fariz Mahyuddi)
* Quick fix to avoid @dom not initialized warnings (Kamal Fariz Mahyuddi)
* Docfix: bad reference to #select method in README (Luke Melia)
* Ensure Rails-style checkboxes work properly (checkboxes followed by a hidden input with the same name)
* Ensure Rails-style checkboxes work properly (checkboxes followed by a hidden
input with the same name)
* Fix Edge Rails (a.k.a. 2.0 RC) compatibility (David Chelimsky)
* Support param hashes nested more than one level (David Chelimsky)
== 0.1.0 / 2007-11-28
* 1 major enhancement
* Birthday!

85
README.rdoc Normal file
View File

@ -0,0 +1,85 @@
= Webrat - Ruby Acceptance Testing for Web applications
- http://gitrdoc.com/brynary/webrat
- http://groups.google.com/group/webrat
- http://webrat.lighthouseapp.com/
- http://github.com/brynary/webrat
- #webrat on Freenode
== Description
Webrat lets you quickly write expressive and robust acceptance tests for a Ruby
web application.
== Features
* Browser Simulator for expressive, high level acceptance testing without the
performance hit and browser dependency of Selenium or Watir (See Webrat::Session)
* Use the same API for Browser Simulator and real Selenium tests using
Webrat::Selenium when necessary (eg. for testing AJAX interactions)
* Supports multiple Ruby web frameworks: Rails, Merb and Sinatra
* Supports popular test frameworks: RSpec, Cucumber, Test::Unit and Shoulda
* Webrat::Matchers API for verifying rendered HTML using CSS, XPath, etc.
== Example
class SignupTest < ActionController::IntegrationTest
def test_trial_account_sign_up
visit home_path
click_link "Sign up"
fill_in "Email", :with => "good@example.com"
select "Free account"
click_button "Register"
end
end
Behind the scenes, Webrat will ensure:
* If a link, form field or button is missing, the test will fail.
* If a URL is invalid, the test will fail.
* If a page load or form submission is unsuccessful, the test will fail.
== Installing Nokogiri
Users of Debian Linux (e.g. Ubuntu) need to run:
sudo apt-get install libxslt1-dev libxml2-dev.
Otherwise the Nokogiri gem, which Webrat depends on, won't install properly.
== Install for Rails
To install the latest release as a gem:
sudo gem install webrat
To install the latest code as a plugin: (_Note:_ This may be less stable than using a released version)
script/plugin install git://github.com/brynary/webrat.git
In your test_helper.rb or env.rb (for Cucumber) add:
require "webrat"
Webrat.configure do |config|
config.mode = :rails
end
== Install with Merb
Merb 1.0 has built-in, seamless Webrat support. Just start using
methods from Webrat::Session in your specs.
== Authors
- Maintained by {Bryan Helmkamp}[mailto:bryan@brynary.com]
- Original code written by {Seth Fitzsimmons}[mailto:seth@mojodna.net]
- Initial development was sponsored by EastMedia[http://www.eastmedia.com]
- Many other contributors. See attributions in History.txt
== License
Copyright (c) 2007-2008 Bryan Helmkamp, Seth Fitzsimmons.
See MIT-LICENSE.txt in this directory.

View File

@ -1,90 +0,0 @@
=== Webrat
- [Code on GitHub](http://github.com/brynary/webrat)
- [Tickets on Lighthouse](http://webrat.lighthouseapp.com/)
=== Description
Webrat (_Ruby Acceptance Testing for Web applications_)
lets you quickly write robust and thorough acceptance tests for a Ruby
web application. By leveraging the DOM, it can run tests similarly to an
in-browser testing solution without the associated performance hit (and
browser dependency). The result is tests that are less fragile and more
effective at verifying that the app will respond properly to users.
When comparing Webrat with an in-browser testing solution like Watir or
Selenium, the primary consideration should be how much JavaScript the
application uses. In-browser testing is currently the only way to test JS, and
that may make it a requirement for your project. If JavaScript is not central
to your application, Webrat is a simpler, effective solution that will let you
run your tests much faster and more frequently.
Initial development was sponsored by [EastMedia](http://www.eastmedia.com).
=== Synopsis
def test_sign_up
visit "/"
click_link "Sign up"
fill_in "Email", :with => "good@example.com"
select "Free account"
click_button "Register"
...
end
Behind the scenes, this will perform the following work:
1. Verify that loading the home page is successful
2. Verify that a "Sign up" link exists on the home page
3. Verify that loading the URL pointed to by the "Sign up" link leads to a
successful page
4. Verify that there is an "Email" input field on the Sign Up page
5. Verify that there is an select field on the Sign Up page with an option for
"Free account"
6. Verify that there is a "Register" submit button on the page
7. Verify that submitting the Sign Up form with the values "good@example.com"
and "Free account" leads to a successful page
Take special note of the things _not_ specified in that test, that might cause
tests to break unnecessarily as your application evolves:
- The input field IDs or names (e.g. "user_email" or "user[email]"), which
could change if you rename a model
- The ID of the form element (Webrat can do a good job of guessing, even if
there are multiple forms on the page.)
- The URLs of links followed
- The URL the form submission should be sent to, which could change if you
adjust your routes or controllers
- The HTTP method for the login request
A test written with Webrat can handle these changes to these without any modifications.
=== Merb
To avoid losing sessions, you need this in environments/test.rb:
Merb::Config.use do |c|
c[:session_store] = 'memory'
end
=== Install
To install the latest release:
sudo gem install webrat
In your stories/helper.rb:
require "webrat"
You could also unpack the gem into vendor/plugins.
=== Authors
- Maintained by [Bryan Helmkamp](mailto:bryan@brynary.com)
- Original code written by [Seth Fitzsimmons](mailto:seth@mojodna.net)
- Many other contributors. See attributions in History.txt
=== License
Copyright (c) 2007 Bryan Helmkamp, Seth Fitzsimmons.
See MIT-LICENSE.txt in this directory.

212
Rakefile
View File

@ -1,89 +1,143 @@
require 'rubygems'
require "rake/gempackagetask"
require 'rake/rdoctask'
require "rake/clean"
require 'spec'
require 'spec/rake/spectask'
require 'spec/rake/verify_rcov'
require './lib/webrat.rb'
begin
require 'spec/rake/spectask'
rescue LoadError
desc "Run specs"
task(:spec) { $stderr.puts '`gem install rspec` to run specs' }
else
desc "Run API and Core specs"
Spec::Rake::SpecTask.new do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = FileList['spec/public/**/*_spec.rb'] + FileList['spec/private/**/*_spec.rb']
end
##############################################################################
# Package && release
##############################################################################
spec = Gem::Specification.new do |s|
s.name = "webrat"
s.version = Webrat::VERSION
s.platform = Gem::Platform::RUBY
s.author = "Bryan Helmkamp"
s.email = "bryan" + "@" + "brynary.com"
s.homepage = "http://github.com/brynary/webrat"
s.summary = "Webrat. Ruby Acceptance Testing for Web applications"
s.bindir = "bin"
s.description = s.summary
s.require_path = "lib"
s.files = %w(History.txt init.rb install.rb MIT-LICENSE.txt README.txt Rakefile TODO.txt) + Dir["lib/**/*"]
# rdoc
s.has_rdoc = true
s.extra_rdoc_files = %w(README.txt MIT-LICENSE.txt)
# Dependencies
s.add_dependency "nokogiri", ">= 1.1.0"
end
Rake::GemPackageTask.new(spec) do |package|
package.gem_spec = spec
end
desc 'Show information about the gem.'
task :debug_gem do
puts spec.to_ruby
end
CLEAN.include ["pkg", "*.gem", "doc", "ri", "coverage"]
desc "Upload rdoc to brynary.com"
task :publish_rdoc => :docs do
sh "scp -r doc/ brynary.com:/apps/uploads/webrat"
end
desc "Run API and Core specs"
Spec::Rake::SpecTask.new do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = FileList['spec/**/*_spec.rb']
end
desc "Run all specs in spec directory with RCov"
Spec::Rake::SpecTask.new(:rcov) do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = FileList['spec/**/*_spec.rb']
t.rcov = true
t.rcov_opts = lambda do
IO.readlines(File.dirname(__FILE__) + "/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
desc "Run all specs in spec directory with RCov"
Spec::Rake::SpecTask.new(:rcov) do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = FileList['spec/public/**/*_spec.rb'] + FileList['spec/private/**/*_spec.rb']
t.rcov = true
t.rcov_opts = lambda do
IO.readlines(File.dirname(__FILE__) + "/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
end
end
end
RCov::VerifyTask.new(:verify_rcov => :rcov) do |t|
t.threshold = 96.2 # Make sure you have rcov 0.7 or higher!
desc "Run everything against multiruby"
task :multiruby do
result = system "multiruby -S rake spec"
raise "Multiruby tests failed" unless result
result = system "jruby -S rake spec"
raise "JRuby tests failed" unless result
Dir.chdir "spec/integration/rails" do
result = system "multiruby -S rake test_unit:rails"
raise "Rails integration tests failed" unless result
result = system "jruby -S rake test_unit:rails"
raise "Rails integration tests failed" unless result
end
Dir.chdir "spec/integration/merb" do
result = system "multiruby -S rake spec"
raise "Merb integration tests failed" unless result
result = system "jruby -S rake spec"
raise "Rails integration tests failed" unless result
end
Dir.chdir "spec/integration/sinatra" do
result = system "multiruby -S rake test"
raise "Sinatra integration tests failed" unless result
result = system "jruby -S rake test"
raise "Sinatra integration tests failed" unless result
end
Dir.chdir "spec/integration/rack" do
result = system "multiruby -S rake test"
raise "Rack integration tests failed" unless result
result = system "jruby -S rake test"
raise "Rack integration tests failed" unless result
end
puts
puts "Multiruby OK!"
end
task :default do
Rake::Task["verify_rcov"].invoke
desc "Run each spec in isolation to test for dependency issues"
task :spec_deps do
Dir["spec/**/*_spec.rb"].each do |test|
if !system("spec #{test} &> /dev/null")
puts "Dependency Issues: #{test}"
end
end
end
desc 'Install the package as a gem.'
task :install_gem => [:clean, :package] do
gem = Dir['pkg/*.gem'].first
sh "sudo gem install --local #{gem}"
namespace :spec do
desc "Run the integration specs"
task :integration => [
"integration:rack",
"integration:sinatra",
"integration:merb",
"integration:mechanize",
"integration:rails:webrat",
"integration:rails:selenium",
]
namespace :integration do
namespace :rails do
task :selenium do
Dir.chdir "spec/integration/rails" do
result = system "rake -rubygems test_unit:selenium"
raise "Rails integration tests failed" unless result
end
end
task :webrat do
Dir.chdir "spec/integration/rails" do
result = system "rake -rubygems test_unit:rails"
raise "Rails integration tests failed" unless result
end
end
end
desc "Run the Merb integration specs"
task :merb do
Dir.chdir "spec/integration/merb" do
result = system "rake -rubygems spec"
raise "Merb integration tests failed" unless result
end
end
desc "Run the Sinatra integration specs"
task :sinatra do
Dir.chdir "spec/integration/sinatra" do
result = system "rake -rubygems test"
raise "Sinatra integration tests failed" unless result
end
end
desc "Run the Sinatra integration specs"
task :rack do
Dir.chdir "spec/integration/rack" do
result = system "rake -rubygems test"
raise "Rack integration tests failed" unless result
end
end
desc "Run the Mechanize integration specs"
task :mechanize do
Dir.chdir "spec/integration/mechanize" do
result = system "rake -rubygems spec"
raise "Mechanize integration tests failed" unless result
end
end
end
end
Rake::RDocTask.new(:docs) do |rd|
rd.main = "README.txt"
rd.rdoc_dir = 'doc'
files = spec.files.grep(/^(lib|bin|ext)|txt$/)
files -= ["TODO.txt"]
files -= files.grep(/\.js$/)
rd.rdoc_files = files.uniq
title = "webrat-#{Webrat::VERSION} Documentation"
rd.options << "-t #{title}"
end
desc 'Removes trailing whitespace'
task :whitespace do
sh %{find . -name '*.rb' -exec sed -i '' 's/ *$//g' {} \\;}
end
task :default => :spec

View File

@ -1,10 +0,0 @@
Run tests in separate processes to eliminate constant-level dependencies
Add rake tasks for selenium runs
Add tests for selenium
Add tests for locator strategies
Use Webrat::Methods for Rails integration
Get file uploads workign with merb
Fix #within scoping for forms that exist outside the scope
Make current_url work with redirections
Track the current form based on the location of the last manipulated input, use this as a default for click_button
Verify SSL support in Rails and Merb

118
Thorfile Normal file
View File

@ -0,0 +1,118 @@
module GemHelpers
def generate_gemspec
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "lib")))
require "webrat"
Gem::Specification.new do |s|
s.name = "webrat"
s.version = Webrat::VERSION
s.author = "Bryan Helmkamp"
s.email = "bryan@brynary.com"
s.homepage = "http://github.com/brynary/webrat"
s.summary = "Ruby Acceptance Testing for Web applications"
s.description = <<-EOS.strip
Webrat lets you quickly write expressive and robust acceptance tests
for a Ruby web application. It supports simulating a browser inside
a Ruby process to avoid the performance hit and browser dependency of
Selenium or Watir, but the same API can also be used to drive real
Selenium tests when necessary (eg. for testing AJAX interactions).
Most Ruby web frameworks and testing frameworks are supported.
EOS
s.rubyforge_project = "webrat"
require "git"
repo = Git.open(".")
s.files = normalize_files(repo.ls_files.keys - repo.lib.ignored_files)
s.test_files = normalize_files(Dir['spec/**/*.rb'] - repo.lib.ignored_files)
s.has_rdoc = true
s.extra_rdoc_files = %w[README.rdoc MIT-LICENSE.txt History.txt]
s.add_dependency "nokogiri", ">= 1.2.0"
s.add_dependency "rack", ">= 1.0"
s.add_dependency "rack-test", ">= 0.5.3"
end
end
def normalize_files(array)
# only keep files, no directories, and sort
array.select do |path|
File.file?(path)
end.sort
end
# Adds extra space when outputting an array. This helps create better version
# control diffs, because otherwise it is all on the same line.
def prettyify_array(gemspec_ruby, array_name)
gemspec_ruby.gsub(/s\.#{array_name.to_s} = \[.+?\]/) do |match|
leadin, files = match[0..-2].split("[")
leadin + "[\n #{files.split(",").join(",\n ")}\n ]"
end
end
def read_gemspec
@read_gemspec ||= eval(File.read("webrat.gemspec"))
end
def sh(command)
puts command
system command
end
end
class Default < Thor
include GemHelpers
desc "gemspec", "Regenerate webrat.gemspec"
def gemspec
File.open("webrat.gemspec", "w") do |file|
gemspec_ruby = generate_gemspec.to_ruby
gemspec_ruby = prettyify_array(gemspec_ruby, :files)
gemspec_ruby = prettyify_array(gemspec_ruby, :test_files)
gemspec_ruby = prettyify_array(gemspec_ruby, :extra_rdoc_files)
file.write gemspec_ruby
end
puts "Wrote gemspec to webrat.gemspec"
read_gemspec.validate
end
desc "build", "Build a webrat gem"
def build
sh "gem build webrat.gemspec"
FileUtils.mkdir_p "pkg"
FileUtils.mv read_gemspec.file_name, "pkg"
end
desc "install", "Install the latest built gem"
def install
sh "gem install --local pkg/#{read_gemspec.file_name}"
end
desc "release", "Release the current branch to GitHub and Gemcutter"
def release
gemspec
build
Release.new.tag
Release.new.gem
end
end
class Release < Thor
include GemHelpers
desc "tag", "Tag the gem on the origin server"
def tag
release_tag = "v#{read_gemspec.version}"
sh "git tag -a #{release_tag} -m 'Tagging #{release_tag}'"
sh "git push origin #{release_tag}"
end
desc "gem", "Push the gem to Gemcutter"
def gem
sh "gem push pkg/#{read_gemspec.file_name}"
end
end

View File

@ -1,3 +0,0 @@
if RAILS_ENV == "test" || RAILS_ENV == "selenium"
require File.join(File.dirname(__FILE__), "lib", "webrat")
end

View File

@ -1 +1 @@
puts IO.read(File.join(File.dirname(__FILE__), 'README'))
puts IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))

View File

@ -1,39 +1,18 @@
require "rubygems"
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
require "rack"
require "nokogiri"
module Webrat
VERSION = '0.3.4'
def self.root #:nodoc:
defined?(RAILS_ROOT) ? RAILS_ROOT : Merb.root
end
def self.require_xml
gem "nokogiri", ">= 1.1.0"
# We need Nokogiri's CSS to XPath support, even if using
# REXML and Hpricot for parsing and searching
require "nokogiri"
if on_java?
require "hpricot"
require "rexml/document"
else
require "webrat/core/nokogiri"
end
end
def self.on_java?
RUBY_PLATFORM =~ /java/
VERSION = "0.7.2.pre"
autoload :MechanizeAdapter, "webrat/adapters/mechanize"
autoload :MerbAdapter, "webrat/adapters/merb"
autoload :RackAdapter, "webrat/adapters/rack"
autoload :RailsAdapter, "webrat/adapters/rails"
autoload :SinatraAdapter, "webrat/adapters/sinatra"
# The common base class for all exceptions raised by Webrat.
class WebratError < StandardError
end
end
Webrat.require_xml
require "webrat/core"
# TODO: This is probably not a good idea.
# Probably better for webrat users to require "webrat/rails" etc. directly
if defined?(RAILS_ENV)
require "webrat/rails"
end

View File

@ -0,0 +1,94 @@
require "mechanize"
module Webrat #:nodoc:
class MechanizeAdapter #:nodoc:
extend Forwardable
Mechanize = WWW::Mechanize if defined?(WWW::Mechanize)
attr_accessor :response
alias :page :response
def initialize(*args)
end
def request_page(url, http_method, data) #:nodoc:
super(absolute_url(url), http_method, data)
end
def get(url, data, headers_argument_not_used = nil)
@response = mechanize.get(url, data)
end
def post(url, data, headers_argument_not_used = nil)
post_data = data.inject({}) do |memo, param|
case param
when Hash
param.each {|attribute, value| memo[attribute] = value }
memo
when Array
case param.last
when Hash
param.last.each {|attribute, value| memo["#{param.first}[#{attribute}]"] = value }
else
memo[param.first] = param.last
end
memo
end
end
@response = mechanize.post(url, post_data)
end
def response_body
@response.content
end
def response_code
@response.code.to_i
end
def response_headers
@response.header
end
def mechanize
@mechanize ||= begin
mechanize = Mechanize.new
mechanize.redirect_ok = false
mechanize
end
end
def_delegators :mechanize, :basic_auth
def absolute_url(url) #:nodoc:
current_host, current_path = split_current_url
if url =~ Regexp.new('^https?://')
url
elsif url =~ Regexp.new('^/')
current_host + url
elsif url =~ Regexp.new('^\.')
current_host + absolute_path(current_path, url)
else
url
end
end
private
def split_current_url
current_url =~ Regexp.new('^(https?://[^/]+)(/.*)?')
[Regexp.last_match(1), Regexp.last_match(2)]
end
def absolute_path(current_path, url)
levels_up = url.split('/').find_all { |x| x == '..' }.size
ancestor = if current_path.nil?
""
else
current_path.split("/")[0..(-1 - levels_up)].join("/")
end
descendent = url.split("/")[levels_up..-1].join
"#{ancestor}/#{descendent}"
end
end
end

View File

@ -0,0 +1,11 @@
require "webrat/integrations/merb"
module Webrat
class MerbAdapter < RackAdapter #:nodoc:
def initialize(context=nil)
app = context.respond_to?(:app) ?
context.app : Merb::Rack::Application.new
super(Rack::Test::Session.new(Rack::MockSession.new(app, "www.example.com")))
end
end
end

View File

@ -0,0 +1,29 @@
require "rack/test"
module Webrat
class RackAdapter
extend Forwardable
def_delegators :@session, :get, :post, :put, :delete
def initialize(session) #:nodoc:
@session = session
end
def response_body
response.body
end
def response_code
response.status
end
def response_headers
response.headers
end
def response
@session.last_response
end
end
end

View File

@ -0,0 +1,77 @@
require "webrat/integrations/rails"
require "action_controller/record_identifier"
module Webrat
class RailsAdapter #:nodoc:
include ActionController::RecordIdentifier
attr_reader :integration_session
def initialize(session)
@integration_session = session
end
def get(url, data, headers = nil)
do_request(:get, url, data, headers)
end
def post(url, data, headers = nil)
do_request(:post, url, data, headers)
end
def put(url, data, headers = nil)
do_request(:put, url, data, headers)
end
def delete(url, data, headers = nil)
do_request(:delete, url, data, headers)
end
def response_body
response.body
end
def response_code
response.code.to_i
end
def response_headers
response.headers
end
def xml_content_type?
response.headers["Content-Type"].to_s =~ /xml/
end
protected
def do_request(http_method, url, data, headers) #:nodoc:
update_protocol(url)
integration_session.send(http_method, normalize_url(url), data, headers)
end
# remove protocol, host and anchor
def normalize_url(href) #:nodoc:
uri = URI.parse(href)
normalized_url = []
normalized_url << "#{uri.scheme}://" if uri.scheme
normalized_url << uri.host if uri.host
normalized_url << ":#{uri.port}" if uri.port && ![80,443].include?(uri.port)
normalized_url << uri.path if uri.path
normalized_url << "?#{uri.query}" if uri.query
normalized_url.join
end
def update_protocol(href) #:nodoc:
if href =~ /^https:/
integration_session.https!(true)
elsif href =~ /^http:/
integration_session.https!(false)
end
end
def response #:nodoc:
integration_session.response
end
end
end

View File

@ -0,0 +1,9 @@
module Webrat
class SinatraAdapter < RackAdapter
def initialize(context)
app = context.respond_to?(:app) ? context.app : Sinatra::Application
super(Rack::Test::Session.new(Rack::MockSession.new(app, "www.example.com")))
end
end
end

View File

@ -1,12 +1,13 @@
require "webrat/core/nokogiri"
require "webrat/core/configuration"
require "webrat/core/xml"
require "webrat/core/logging"
require "webrat/core/flunk"
require "webrat/core/form"
require "webrat/core/elements/form"
require "webrat/core/scope"
require "webrat/core/link"
require "webrat/core/area"
require "webrat/core/label"
require "webrat/core/select_option"
require "webrat/core/elements/link"
require "webrat/core/elements/area"
require "webrat/core/elements/label"
require "webrat/core/elements/select_option"
require "webrat/core/session"
require "webrat/core/methods"
require "webrat/core/matchers"
require "webrat/core/save_and_open_page"

114
lib/webrat/core/configuration.rb Executable file
View File

@ -0,0 +1,114 @@
require "webrat/core_extensions/deprecate"
require "pathname"
module Webrat
# Configures Webrat. If this is not done, Webrat will be created
# with all of the default settings.
def self.configure(configuration = Webrat.configuration)
yield configuration if block_given?
@@configuration = configuration
end
def self.configuration # :nodoc:
@@configuration ||= Webrat::Configuration.new
end
# Webrat can be configured using the Webrat.configure method. For example:
#
# Webrat.configure do |config|
# config.mode = :sinatra
# end
class Configuration
# Webrat's mode, set automatically when requiring webrat/rails, webrat/merb, etc.
attr_reader :mode # :nodoc:
# Save and open pages with error status codes (500-599) in a browser? Defualts to true.
attr_writer :open_error_files
# Save and open page storage directory, defaults to "tmp" under current directory if exists, otherwise current directory
attr_accessor :saved_pages_dir
# Which rails environment should the selenium tests be run in? Defaults to test.
attr_accessor :application_environment
webrat_deprecate :selenium_environment, :application_environment
webrat_deprecate :selenium_environment=, :application_environment=
# Which port is the application running on for selenium testing? Defaults to 3001.
attr_accessor :application_port
webrat_deprecate :selenium_port, :application_port
webrat_deprecate :selenium_port=, :application_port=
# Which port should selenium use to access the application. Defaults to application_port
attr_writer :application_port_for_selenium
def application_port_for_selenium
@application_port_for_selenium || self.application_port
end
# Which underlying app framework we're testing with selenium
attr_accessor :application_framework
# Which server the application is running on for selenium testing? Defaults to localhost
attr_accessor :application_address
# Which server Selenium server is running on. Defaults to nil(server starts in webrat process and runs locally)
attr_accessor :selenium_server_address
# Which server Selenium port is running on. Defaults to 4444
attr_accessor :selenium_server_port
# Set the key that Selenium uses to determine the browser running. Default *firefox
attr_accessor :selenium_browser_key
# Set the timeout for waiting for the browser process to start
attr_accessor :selenium_browser_startup_timeout
# Set the firefox profile for selenium to use
attr_accessor :selenium_firefox_profile
# How many redirects to the same URL should be halted as an infinite redirect
# loop? Defaults to 10
attr_accessor :infinite_redirect_limit
# Print out the full HTML on wait failure
# Defaults to false
attr_accessor :selenium_verbose_output
def initialize # :nodoc:
self.open_error_files = true
self.application_environment = :test
self.application_port = 3001
self.application_address = 'localhost'
self.application_framework = :rails
self.selenium_server_port = 4444
self.infinite_redirect_limit = 10
self.selenium_browser_key = '*firefox'
self.selenium_browser_startup_timeout = 5
self.selenium_verbose_output = false
tmp_dir = Pathname.new(Dir.pwd).join("tmp")
self.saved_pages_dir = tmp_dir.exist? ? tmp_dir : Dir.pwd
end
def open_error_files? #:nodoc:
@open_error_files ? true : false
end
# Allows setting of webrat's mode, valid modes are:
# :rails, :selenium, :rack, :sinatra, :mechanize, :merb
def mode=(mode)
@mode = mode.to_sym
begin
require("webrat/integrations/#{mode}")
rescue LoadError
# Only some modes have integration code that needs to
# be loaded, so this is OK
end
end
end
end

View File

@ -1,35 +1,22 @@
require "webrat/core/elements/element"
module Webrat
class Area #:nodoc:
def initialize(session, element)
@session = session
@element = element
class Area < Element #:nodoc:
def self.xpath_search
[".//area"]
end
def click(method = nil, options = {})
@session.request_page(absolute_href, :get, {})
end
def matches_text?(id_or_title)
matcher = /#{Regexp.escape(id_or_title.to_s)}/i
title =~ matcher || id =~ matcher
end
protected
protected
def href
@element["href"]
end
def title
@element["title"]
end
def id
@element["id"]
end
def absolute_href
if href =~ /^\?/
"#{@session.current_url}#{href}"
@ -39,6 +26,6 @@ module Webrat
href
end
end
end
end
end

View File

@ -0,0 +1,33 @@
module Webrat
class Element # :nodoc:
def self.load_all(session, dom)
dom.xpath(*xpath_search).map do |element|
load(session, element)
end
end
def self.load(session, element)
return nil if element.nil?
session.elements[element.path] ||= self.new(session, element)
end
attr_reader :element
def initialize(session, element)
@session = session
@element = element
end
def path
@element.path
end
def inspect
"#<#{self.class} @element=#{element.inspect}>"
end
end
end

View File

@ -0,0 +1,438 @@
require "cgi"
require "digest/md5"
require "webrat/core_extensions/blank"
require "webrat/core_extensions/nil_to_query_string"
require "webrat/core/elements/element"
module Webrat
# Raised when Webrat is asked to manipulate a disabled form field
class DisabledFieldError < WebratError
end
class Field < Element #:nodoc:
attr_reader :value
def self.xpath_search
".//button|.//input|.//textarea|.//select"
end
def self.xpath_search_excluding_hidden
[".//button", ".//input[ @type != 'hidden']", ".//textarea", ".//select"]
end
def self.field_classes
@field_classes || []
end
def self.inherited(klass)
@field_classes ||= []
@field_classes << klass
# raise args.inspect
end
def self.load(session, element)
return nil if element.nil?
session.elements[element.path] ||= field_class(element).new(session, element)
end
def self.field_class(element)
case element.name
when "button" then ButtonField
when "select"
if element.attributes["multiple"].nil?
SelectField
else
MultipleSelectField
end
when "textarea" then TextareaField
else
case element["type"]
when "checkbox" then CheckboxField
when "hidden" then HiddenField
when "radio" then RadioField
when "password" then PasswordField
when "file" then FileField
when "reset" then ResetField
when "submit" then ButtonField
when "button" then ButtonField
when "image" then ButtonField
else TextField
end
end
end
def initialize(*args)
super
@value = default_value
end
def label_text
return nil if labels.empty?
labels.first.text
end
def id
@element["id"]
end
def disabled?
@element.attributes.has_key?("disabled") && @element["disabled"] != 'false'
end
def raise_error_if_disabled
return unless disabled?
raise DisabledFieldError.new("Cannot interact with disabled form element (#{self})")
end
def to_query_string
return nil if disabled?
query_string = case Webrat.configuration.mode
when :rails, :merb, :rack, :sinatra
build_query_string
when :mechanize
build_query_string(false)
end
query_string
end
def set(value)
@value = value
end
def unset
@value = default_value
end
protected
def form
Form.load(@session, form_element)
end
def form_element
parent = @element.parent
while parent.respond_to?(:parent)
return parent if parent.name == 'form'
parent = parent.parent
end
end
def name
@element["name"]
end
def build_query_string(escape_value=true)
if @value.is_a?(Array)
@value.collect {|value| "#{name}=#{ escape_value ? escape(value) : value }" }.join("&")
else
"#{name}=#{ escape_value ? escape(value) : value }"
end
end
def escape(value)
CGI.escape(value.to_s)
end
def escaped_value
CGI.escape(@value.to_s)
end
def labels
@labels ||= label_elements.map do |element|
Label.load(@session, element)
end
end
def label_elements
return @label_elements unless @label_elements.nil?
@label_elements = []
parent = @element.parent
while parent.respond_to?(:parent)
if parent.name == 'label'
@label_elements.push parent
break
end
parent = parent.parent
end
unless id.blank?
@label_elements += form.element.xpath(".//label[@for = '#{id}']")
end
@label_elements
end
def default_value
@element["value"]
end
end
class ButtonField < Field #:nodoc:
def self.xpath_search
[".//button", ".//input[@type = 'submit']", ".//input[@type = 'button']", ".//input[@type = 'image']"]
end
def to_query_string
return nil if @value.nil?
super
end
def default_value
nil
end
def click
raise_error_if_disabled
set(@element["value"]) unless @element["name"].blank?
form.submit
end
end
class HiddenField < Field #:nodoc:
def self.xpath_search
".//input[@type = 'hidden']"
end
def to_query_string
if collection_name?
super
else
checkbox_with_same_name = form.field_named(name, CheckboxField)
if checkbox_with_same_name.to_query_string.blank?
super
else
nil
end
end
end
protected
def collection_name?
name =~ /\[\]/
end
end
class CheckboxField < Field #:nodoc:
def self.xpath_search
".//input[@type = 'checkbox']"
end
def to_query_string
return nil if @value.nil?
super
end
def check
raise_error_if_disabled
set(@element["value"] || "on")
end
def checked?
@element["checked"] == "checked"
end
def uncheck
raise_error_if_disabled
set(nil)
end
protected
def default_value
if @element["checked"] == "checked"
@element["value"] || "on"
else
nil
end
end
end
class PasswordField < Field #:nodoc:
def self.xpath_search
".//input[@type = 'password']"
end
end
class RadioField < Field #:nodoc:
def self.xpath_search
".//input[@type = 'radio']"
end
def to_query_string
return nil if @value.nil?
super
end
def choose
raise_error_if_disabled
other_options.each do |option|
option.set(nil)
end
set(@element["value"] || "on")
end
def checked?
@element["checked"] == "checked"
end
protected
def other_options
form.fields.select { |f| f.name == name }
end
def default_value
if @element["checked"] == "checked"
@element["value"] || "on"
else
nil
end
end
end
class TextareaField < Field #:nodoc:
def self.xpath_search
".//textarea"
end
protected
def default_value
@element.inner_html
end
end
class FileField < Field #:nodoc:
def self.xpath_search
".//input[@type = 'file']"
end
attr_accessor :content_type
def set(value, content_type = nil)
@original_value = @value
@content_type ||= content_type
super(value)
end
def digest_value
@value ? Digest::MD5.hexdigest(self.object_id.to_s) : ""
end
def to_query_string
@value.nil? ? set("") : set(digest_value)
super
end
def test_uploaded_file
return "" if @original_value.blank?
case Webrat.configuration.mode
when :rails
if content_type
ActionController::TestUploadedFile.new(@original_value, content_type)
else
ActionController::TestUploadedFile.new(@original_value)
end
when :rack, :merb
Rack::Test::UploadedFile.new(@original_value, content_type)
end
end
end
class TextField < Field #:nodoc:
def self.xpath_search
[".//input[@type = 'text']", ".//input[not(@type)]"]
end
end
class ResetField < Field #:nodoc:
def self.xpath_search
[".//input[@type = 'reset']"]
end
end
class SelectField < Field #:nodoc:
def self.xpath_search
[".//select[not(@multiple)]"]
end
def options
@options ||= SelectOption.load_all(@session, @element)
end
def unset(value)
@value = nil
end
protected
def default_value
selected_options = @element.xpath(".//option[@selected = 'selected']")
selected_options = @element.xpath(".//option[position() = 1]") if selected_options.empty?
selected_options.map do |option|
return "" if option.nil?
option["value"] || option.inner_html
end.uniq.first
end
end
class MultipleSelectField < Field #:nodoc:
def self.xpath_search
[".//select[@multiple='multiple']"]
end
def options
@options ||= SelectOption.load_all(@session, @element)
end
def set(value)
@value << value
end
def unset(value)
@value.delete(value)
end
protected
# Overwrite SelectField definition because we don't want to select the first option
# (mutliples don't select the first option unlike their non multiple versions)
def default_value
selected_options = @element.xpath(".//option[@selected = 'selected']")
selected_options.map do |option|
return "" if option.nil?
option["value"] || option.inner_html
end.uniq
end
end
end

View File

@ -0,0 +1,127 @@
require "webrat/core/elements/field"
require "webrat/core_extensions/blank"
require "webrat/core/elements/element"
require "webrat/core/locators/field_named_locator"
module Webrat
class Form < Element #:nodoc:
attr_reader :element
def self.xpath_search
[".//form"]
end
def fields
@fields ||= Field.load_all(@session, @element)
end
def submit
@session.request_page(form_action, form_method, params)
end
def field_named(name, *field_types)
Webrat::Locators::FieldNamedLocator.new(@session, dom, name, *field_types).locate
end
protected
def dom
@session.dom.xpath(path).first
end
def fields_by_type(field_types)
if field_types.any?
fields.select { |f| field_types.include?(f.class) }
else
fields
end
end
# iterate over all form fields to build a request querystring to get params from it,
# for file_field we made a work around to pass a digest as value to later replace it
# in params hash with the real file.
def params
query_string = []
replaces = {}
fields.each do |field|
next if field.to_query_string.nil?
replaces.merge!({field.digest_value => field.test_uploaded_file}) if field.is_a?(FileField)
query_string << field.to_query_string
end
query_params = self.class.query_string_to_params(query_string.join('&'))
query_params = self.class.replace_params_values(query_params, replaces)
self.class.unescape_params(query_params)
end
def form_method
@element["method"].blank? ? :get : @element["method"].downcase
end
def form_action
@element["action"].blank? ? @session.current_url : @element["action"]
end
def self.replace_param_value(params, oval, nval)
output = Hash.new
params.each do |key, value|
case value
when Hash
value = replace_param_value(value, oval, nval)
when Array
value = value.map { |o| o == oval ? nval : ( o.is_a?(Hash) ? replace_param_value(o, oval, nval) : o) }
when oval
value = nval
end
output[key] = value
end
output
end
def self.replace_params_values(params, values)
values.each do |key, value|
params = replace_param_value(params, key, value)
end
params
end
def self.unescape_params(params)
case params.class.name
when 'Hash', 'Mash'
params.each { |key,value| params[key] = unescape_params(value) }
params
when 'Array'
params.collect { |value| unescape_params(value) }
else
params.is_a?(String) ? CGI.unescapeHTML(params) : params
end
end
def self.query_string_to_params(query_string)
case Webrat.configuration.mode
when :rails
parse_rails_request_params(query_string)
when :merb
::Merb::Parse.query(query_string)
when :rack, :sinatra
Rack::Utils.parse_nested_query(query_string)
else
Hash[query_string.split('&').map {|query| [ query.split('=').first, query.split('=').last ]}]
end
end
def self.parse_rails_request_params(query_string)
if defined?(ActionController::AbstractRequest)
ActionController::AbstractRequest.parse_query_parameters(query_string)
elsif defined?(ActionController::UrlEncodedPairParser)
ActionController::UrlEncodedPairParser.parse_query_parameters(query_string)
else
Rack::Utils.parse_nested_query(query_string)
end
end
end
end

View File

@ -0,0 +1,31 @@
require "webrat/core/elements/element"
module Webrat
class Label < Element #:nodoc:
attr_reader :element
def self.xpath_search
[".//label"]
end
def for_id
@element["for"]
end
def field
Field.load(@session, field_element)
end
protected
def field_element
if for_id.blank?
@element.xpath(*Field.xpath_search_excluding_hidden).first
else
@session.current_dom.css("#" + for_id).first
end
end
end
end

View File

@ -1,50 +1,40 @@
require "English"
require "webrat/core_extensions/blank"
require "webrat/core/elements/element"
module Webrat
class Link #:nodoc:
def initialize(session, element)
@session = session
@element = element
class Link < Element #:nodoc:
def self.xpath_search
[".//a[@href]"]
end
def click(options = {})
method = options[:method] || http_method
return if href =~ /^#/ && method == :get
options[:javascript] = true if options[:javascript].nil?
if options[:javascript]
@session.request_page(absolute_href, method, data)
else
@session.request_page(absolute_href, :get, {})
end
end
def matches_text?(link_text)
html = text.gsub('&#xA0;',' ')
if link_text.is_a?(Regexp)
matcher = link_text
else
matcher = /#{Regexp.escape(link_text.to_s)}/i
end
html =~ matcher || title =~ matcher
end
def text
@element.inner_html
end
protected
def id
@element["id"]
end
def data
authenticity_token.blank? ? {} : {"authenticity_token" => authenticity_token}
end
def title
@element['title']
@element["title"]
end
def href
@ -54,23 +44,23 @@ module Webrat
def absolute_href
if href =~ /^\?/
"#{@session.current_url}#{href}"
elsif href !~ %r{^https?://www.example.com(/.*)} && (href !~ /^\//)
elsif href !~ %r{^https?://} && (href !~ /^\//)
"#{@session.current_url}/#{href}"
else
href
end
end
def authenticity_token
return unless onclick && onclick.include?("s.setAttribute('name', 'authenticity_token');") &&
onclick =~ /s\.setAttribute\('value', '([a-f0-9]{40})'\);/
( onclick =~ /s\.setAttribute\('value', '([a-f0-9]{40})'\);/ || onclick =~ /s\.setAttribute\('value', '(.{44})'\);/ )
$LAST_MATCH_INFO.captures.first
end
def onclick
@element["onclick"]
end
def http_method
if !onclick.blank? && onclick.include?("f.submit()")
http_method_from_js_form
@ -92,8 +82,10 @@ module Webrat
:delete
elsif onclick.include?("m.setAttribute('value', 'put')")
:put
elsif onclick.include?("m.setAttribute('value', 'post')")
:post
else
raise "No HTTP method for _method param in #{onclick.inspect}"
raise Webrat::WebratError.new("No HTTP method for _method param in #{onclick.inspect}")
end
end

View File

@ -0,0 +1,48 @@
require "webrat/core/elements/element"
module Webrat
class SelectOption < Element #:nodoc:
def self.xpath_search
[".//option"]
end
def choose
select.raise_error_if_disabled
select.set(value)
end
def unchoose
select.raise_error_if_disabled
select.unset(value)
end
def inner_text
@element.inner_text
end
protected
def select
SelectField.load(@session, select_element)
end
def select_element
parent = @element.parent
while parent.respond_to?(:parent)
return parent if parent.name == 'select'
parent = parent.parent
end
end
def value
@element["value"] || @element.inner_html
end
def label
@element.inner_html
end
end
end

View File

@ -1,332 +0,0 @@
require "cgi"
require "webrat/core_extensions/blank"
require "webrat/core_extensions/nil_to_param"
module Webrat
class Field #:nodoc:
def self.class_for_element(element)
if element.name == "input"
if %w[submit image].include?(element["type"])
field_class = "button"
else
field_class = element["type"] || "text" #default type; 'type' attribute is not mandatory
end
else
field_class = element.name
end
Webrat.const_get("#{field_class.capitalize}Field")
rescue NameError
raise "Invalid field element: #{element.inspect}"
end
def initialize(form, element)
@form = form
@element = element
@value = default_value
end
def label_text
return nil if labels.empty?
labels.first.text
end
def matches_id?(id)
@element["id"] == id.to_s
end
def matches_name?(name)
@element["name"] == name.to_s
end
def matches_label?(label_text)
return false if labels.empty?
labels.any? { |label| label.matches_text?(label_text) }
end
def matches_alt?(alt)
@element["alt"] =~ /^\W*#{Regexp.escape(alt.to_s)}/i
end
def disabled?
@element.attributes.has_key?("disabled") && @element["disabled"] != 'false'
end
def raise_error_if_disabled
raise "Cannot interact with disabled form element (#{self})" if disabled?
end
def to_param
return nil if disabled?
key_and_value = "#{name}=#{escaped_value}"
if defined?(CGIMethods)
CGIMethods.parse_query_parameters(key_and_value)
elsif defined?(ActionController::AbstractRequest)
ActionController::AbstractRequest.parse_query_parameters(key_and_value)
else
::Merb::Parse.query(key_and_value)
end
end
def set(value)
@value = value
end
def unset
@value = default_value
end
protected
def id
@element["id"]
end
def name
@element["name"]
end
def escaped_value
CGI.escape(@value.to_s)
end
def labels
@labels ||= label_elements.map { |element| Label.new(self, element) }
end
def label_elements
return @label_elements unless @label_elements.nil?
@label_elements = []
parent = @element.parent
while parent.respond_to?(:parent)
if parent.name == 'label'
@label_elements.push parent
break
end
parent = parent.parent
end
unless id.blank?
@label_elements += @form.element.search("label[@for='#{id}']")
end
@label_elements
end
def default_value
@element["value"]
end
def replace_param_value(params, oval, nval)
output = Hash.new
params.each do |key, value|
case value
when Hash
value = replace_param_value(value, oval, nval)
when Array
value = value.map { |o| o == oval ? nval : oval }
when oval
value = nval
end
output[key] = value
end
output
end
end
class ButtonField < Field #:nodoc:
def matches_text?(text)
@element.inner_html =~ /#{Regexp.escape(text.to_s)}/i
end
def matches_value?(value)
@element["value"] =~ /^\W*#{Regexp.escape(value.to_s)}/i || matches_text?(value) || matches_alt?(value)
end
def to_param
return nil if @value.nil?
super
end
def default_value
nil
end
def click
raise_error_if_disabled
set(@element["value"]) unless @element["name"].blank?
@form.submit
end
end
class HiddenField < Field #:nodoc:
def to_param
if collection_name?
super
else
checkbox_with_same_name = @form.field(name, CheckboxField)
if checkbox_with_same_name.to_param.blank?
super
else
nil
end
end
end
protected
def collection_name?
name =~ /\[\]/
end
end
class CheckboxField < Field #:nodoc:
def to_param
return nil if @value.nil?
super
end
def check
raise_error_if_disabled
set(@element["value"] || "on")
end
def checked?
@element["checked"] == "checked"
end
def uncheck
raise_error_if_disabled
set(nil)
end
protected
def default_value
if @element["checked"] == "checked"
@element["value"] || "on"
else
nil
end
end
end
class PasswordField < Field #:nodoc:
end
class RadioField < Field #:nodoc:
def to_param
return nil if @value.nil?
super
end
def choose
raise_error_if_disabled
other_options.each do |option|
option.set(nil)
end
set(@element["value"] || "on")
end
protected
def other_options
@form.fields.select { |f| f.name == name }
end
def default_value
if @element["checked"] == "checked"
@element["value"] || "on"
else
nil
end
end
end
class TextareaField < Field #:nodoc:
protected
def default_value
@element.inner_html
end
end
class FileField < Field #:nodoc:
attr_accessor :content_type
def set(value, content_type = nil)
super(value)
@content_type = content_type
end
def to_param
if @value.nil?
super
else
replace_param_value(super, @value, test_uploaded_file)
end
end
protected
def test_uploaded_file
if content_type
ActionController::TestUploadedFile.new(@value, content_type)
else
ActionController::TestUploadedFile.new(@value)
end
end
end
class TextField < Field #:nodoc:
end
class ResetField < Field #:nodoc:
end
class SelectField < Field #:nodoc:
def find_option(text)
options.detect { |o| o.matches_text?(text) }
end
protected
def default_value
selected_options = @element.search(".//option[@selected='selected']")
selected_options = @element.search(".//option[position() = 1]") if selected_options.empty?
selected_options.map do |option|
return "" if option.nil?
option["value"] || option.inner_html
end
end
def options
option_elements.map { |oe| SelectOption.new(self, oe) }
end
def option_elements
@element.search(".//option")
end
end
end

View File

@ -1,7 +0,0 @@
module Flunk
def flunk(message) #:nodoc:
raise message
end
end

View File

@ -1,130 +0,0 @@
require "webrat/core/field"
require "webrat/core_extensions/blank"
module Webrat
class Form #:nodoc:
attr_reader :element
def initialize(session, element)
@session = session
@element = element
@fields = nil
end
def field(locator, *field_types)
field_with_id(locator, *field_types) ||
field_named(locator, *field_types) ||
field_labeled(locator, *field_types) ||
nil
end
def find_select_option(option_text)
select_fields = fields_by_type([SelectField])
select_fields.each do |select_field|
result = select_field.find_option(option_text)
return result if result
end
nil
end
def find_button(value = nil)
return fields_by_type([ButtonField]).first if value.nil?
possible_buttons = fields_by_type([ButtonField])
possible_buttons.detect { |possible_button| possible_button.matches_id?(value) } ||
possible_buttons.detect { |possible_button| possible_button.matches_value?(value) }
end
def fields
return @fields if @fields
@fields = (@element.search(".//button", ".//input", ".//textarea", ".//select")).collect do |field_element|
Field.class_for_element(field_element).new(self, field_element)
end
end
def submit
@session.request_page(form_action, form_method, params)
end
def field_with_id(id, *field_types)
possible_fields = fields_by_type(field_types)
possible_fields.detect { |possible_field| possible_field.matches_id?(id) }
end
def field_named(name, *field_types)
possible_fields = fields_by_type(field_types)
possible_fields.detect { |possible_field| possible_field.matches_name?(name) }
end
def field_labeled(label, *field_types)
possible_fields = fields_by_type(field_types)
matching_fields = possible_fields.select do |possible_field|
possible_field.matches_label?(label)
end
matching_fields.min { |a, b| a.label_text.length <=> b.label_text.length }
end
protected
def fields_by_type(field_types)
if field_types.any?
fields.select { |f| field_types.include?(f.class) }
else
fields
end
end
def params
all_params = {}
fields.each do |field|
next if field.to_param.nil?
merge(all_params, field.to_param)
end
all_params
end
def form_method
@element["method"].blank? ? :get : @element["method"].downcase
end
def form_action
@element["action"].blank? ? @session.current_url : @element["action"]
end
HASH = [Hash, HashWithIndifferentAccess] rescue [Hash]
def merge(all_params, new_param)
new_param.each do |key, value|
case all_params[key]
when *HASH
merge_hash_values(all_params[key], value)
when Array
all_params[key] += value
else
all_params[key] = value
end
end
end
def merge_hash_values(a, b) # :nodoc:
a.keys.each do |k|
if b.has_key?(k)
case [a[k], b[k]].map{|value| value.class}
when [Hash, Hash]
a[k] = merge_hash_values(a[k], b[k])
b.delete(k)
when [Array, Array]
a[k] += b[k]
b.delete(k)
end
end
end
a.merge!(b)
end
end
end

View File

@ -1,18 +0,0 @@
module Webrat
class Label #:nodoc:
def initialize(field, element)
@field = field
@element = element
end
def matches_text?(label_text)
text =~ /^\W*#{Regexp.escape(label_text.to_s)}\b/i
end
def text
@element.inner_text
end
end
end

View File

@ -1,92 +1,20 @@
require "webrat/core_extensions/detect_mapped"
require "webrat/core/locators/area_locator"
require "webrat/core/locators/button_locator"
require "webrat/core/locators/field_labeled_locator"
require "webrat/core/locators/label_locator"
require "webrat/core/locators/field_named_locator"
require "webrat/core/locators/field_by_id_locator"
require "webrat/core/locators/select_option_locator"
require "webrat/core/locators/link_locator"
require "webrat/core/locators/field_locator"
require "webrat/core/locators/form_locator"
module Webrat
module Locators
def field(*args)
# This is the default locator strategy
find_field_with_id(*args) ||
find_field_named(*args) ||
field_labeled(*args) ||
flunk("Could not find field: #{args.inspect}")
end
def field_labeled(label, *field_types)
find_field_labeled(label, *field_types) ||
flunk("Could not find field labeled #{label.inspect}")
def field_by_xpath(xpath)
Field.load(@session, dom.xpath(xpath).first)
end
def field_named(name, *field_types)
find_field_named(name, *field_types) ||
flunk("Could not find field named #{name.inspect}")
end
def field_with_id(id, *field_types)
find_field_with_id(id, *field_types) ||
flunk("Could not find field with id #{id.inspect}")
end
def find_field_labeled(label, *field_types) #:nodoc:
forms.detect_mapped do |form|
form.field_labeled(label, *field_types)
end
end
def find_field_named(name, *field_types) #:nodoc:
forms.detect_mapped do |form|
form.field_named(name, *field_types)
end
end
def find_field_with_id(id, *field_types) #:nodoc:
forms.detect_mapped do |form|
form.field_with_id(id, *field_types)
end
end
def find_select_option(option_text, id_or_name_or_label) #:nodoc:
if id_or_name_or_label
field = field(id_or_name_or_label, SelectField)
return field.find_option(option_text)
else
select_option = forms.detect_mapped do |form|
form.find_select_option(option_text)
end
return select_option if select_option
end
flunk("Could not find option #{option_text.inspect}")
end
def find_button(value) #:nodoc:
button = forms.detect_mapped do |form|
form.find_button(value)
end
if button
return button
else
flunk("Could not find button #{value.inspect}")
end
end
def find_area(area_name) #:nodoc:
areas.detect { |area| area.matches_text?(area_name) } ||
flunk("Could not find area with name #{area_name}")
end
def find_link(text) #:nodoc:
matching_links = links.select do |possible_link|
possible_link.matches_text?(text)
end
if matching_links.any?
matching_links.min { |a, b| a.text.length <=> b.text.length }
else
flunk("Could not find link with text #{text.inspect}")
end
end
end
end
end

View File

@ -0,0 +1,38 @@
require "webrat/core/locators/locator"
module Webrat
module Locators
class AreaLocator < Locator # :nodoc:
def locate
Area.load(@session, area_element)
end
def area_element
area_elements.detect do |area_element|
area_element["title"] =~ matcher ||
area_element["id"] =~ matcher
end
end
def matcher
/#{Regexp.escape(@value.to_s)}/i
end
def area_elements
@dom.xpath(*Area.xpath_search)
end
def error_message
"Could not find area with name #{@value}"
end
end
def find_area(id_or_title) #:nodoc:
AreaLocator.new(@session, dom, id_or_title).locate!
end
end
end

View File

@ -0,0 +1,54 @@
require "webrat/core/locators/locator"
module Webrat
module Locators
class ButtonLocator < Locator # :nodoc:
def locate
ButtonField.load(@session, button_element)
end
def button_element
button_elements.detect do |element|
@value.nil? ||
matches_id?(element) ||
matches_value?(element) ||
matches_html?(element) ||
matches_alt?(element)
end
end
def matches_id?(element)
(@value.is_a?(Regexp) && element["id"] =~ @value) ||
(!@value.is_a?(Regexp) && element["id"] == @value.to_s)
end
def matches_value?(element)
element["value"] =~ /^\W*#{Regexp.escape(@value.to_s)}/i
end
def matches_html?(element)
element.inner_html =~ /#{Regexp.escape(@value.to_s)}/i
end
def matches_alt?(element)
element["alt"] =~ /^\W*#{Regexp.escape(@value.to_s)}/i
end
def button_elements
@dom.xpath(*ButtonField.xpath_search)
end
def error_message
"Could not find button #{@value.inspect}"
end
end
def find_button(value) #:nodoc:
ButtonLocator.new(@session, dom, value).locate!
end
end
end

View File

@ -0,0 +1,37 @@
require "webrat/core/locators/locator"
module Webrat
module Locators
class FieldByIdLocator < Locator # :nodoc:
def locate
Field.load(@session, field_element)
end
def field_element
field_elements.detect do |field_element|
if @value.is_a?(Regexp)
field_element["id"] =~ @value
else
field_element["id"] == @value.to_s
end
end
end
def field_elements
@dom.xpath(*Field.xpath_search)
end
def error_message
"Could not find field with id #{@value.inspect}"
end
end
def field_with_id(id, *field_types)
FieldByIdLocator.new(@session, dom, id, *field_types).locate!
end
end
end

View File

@ -0,0 +1,56 @@
require "webrat/core_extensions/detect_mapped"
require "webrat/core/locators/locator"
module Webrat
module Locators
class FieldLabeledLocator < Locator # :nodoc:
def locate
matching_labels.any? && matching_labels.detect_mapped { |label| label.field }
end
def matching_labels
matching_label_elements.sort_by do |label_element|
text(label_element).length
end.map do |label_element|
Label.load(@session, label_element)
end
end
def matching_label_elements
label_elements.select do |label_element|
text(label_element) =~ /^\W*#{Regexp.escape(@value.to_s)}(\b|\Z)/i
end
end
def label_elements
@dom.xpath(*Label.xpath_search)
end
def error_message
"Could not find field labeled #{@value.inspect}"
end
def text(element)
str = element.inner_text
str.gsub!("\n","")
str.strip!
str.squeeze!(" ")
str
end
end
# Locates a form field based on a <tt>label</tt> element in the HTML source.
# This can be useful in order to verify that a field is pre-filled with the
# correct value.
#
# Example:
# field_labeled("First name").value.should == "Bryan"
def field_labeled(label, *field_types)
FieldLabeledLocator.new(@session, dom, label, *field_types).locate!
end
end
end

View File

@ -0,0 +1,25 @@
require "webrat/core/locators/locator"
module Webrat
module Locators
class FieldLocator < Locator # :nodoc:
def locate
FieldByIdLocator.new(@session, @dom, @value).locate ||
FieldNamedLocator.new(@session, @dom, @value, *@field_types).locate ||
FieldLabeledLocator.new(@session, @dom, @value, *@field_types).locate
end
def error_message
"Could not find field: #{@value.inspect}"
end
end
def field(*args) # :nodoc:
FieldLocator.new(@session, dom, *args).locate!
end
end
end

View File

@ -0,0 +1,41 @@
require "webrat/core/locators/locator"
module Webrat
module Locators
class FieldNamedLocator < Locator # :nodoc:
def locate
Field.load(@session, field_element)
end
def field_element
field_elements.detect do |field_element|
field_element["name"] == @value.to_s
end
end
def field_elements
@dom.xpath(*xpath_searches)
end
def xpath_searches
if @field_types.any?
@field_types.map { |field_type| field_type.xpath_search }.flatten
else
Field.xpath_search
end
end
def error_message
"Could not find field named #{@value.inspect}"
end
end
def field_named(name, *field_types)
FieldNamedLocator.new(@session, dom, name, *field_types).locate!
end
end
end

View File

@ -0,0 +1,19 @@
require "webrat/core/locators/locator"
module Webrat
module Locators
class FormLocator < Locator # :nodoc:
def locate
Form.load(@session, form_element)
end
def form_element
@dom.css("#" + @value).first || @dom.css(@value).first
end
end
end
end

View File

@ -0,0 +1,34 @@
require "webrat/core_extensions/detect_mapped"
require "webrat/core/locators/locator"
module Webrat
module Locators
class LabelLocator < Locator # :nodoc:
def locate
Label.load(@session, label_element)
end
def label_element
label_elements.detect do |label_element|
text(label_element) =~ /^\W*#{Regexp.escape(@value.to_s)}(\b|\Z)/i
end
end
def label_elements
@dom.xpath(*Label.xpath_search)
end
def text(label_element)
str = label_element.inner_text
str.gsub!("\n","")
str.strip!
str.squeeze!(" ")
str
end
end
end
end

View File

@ -0,0 +1,74 @@
require "webrat/core/locators/locator"
module Webrat
module Locators
class LinkLocator < Locator # :nodoc:
def locate
Link.load(@session, link_element)
end
def link_element
matching_links.min { |a, b| a.inner_text.length <=> b.inner_text.length }
end
def matching_links
@matching_links ||= link_elements.select do |link_element|
matches_text?(link_element) ||
matches_id?(link_element)
end
end
def matches_text?(link)
if @value.is_a?(Regexp)
matcher = @value
else
matcher = /#{Regexp.escape(@value.to_s)}/i
end
replace_nbsp(link.inner_text) =~ matcher ||
replace_nbsp_ref(link.inner_html) =~ matcher ||
link["title"] =~ matcher
end
def matches_id?(link)
if @value.is_a?(Regexp)
link["id"] =~ @value ? true : false
else
link["id"] == @value ? true : false
end
end
def link_elements
@dom.xpath(*Link.xpath_search)
end
def replace_nbsp(str)
if str.respond_to?(:valid_encoding?)
if str.valid_encoding?
str.gsub(/\xc2\xa0/u, ' ')
else
str.force_encoding('UTF-8').gsub(/\xc2\xa0/u, ' ')
end
else
str.gsub(/\xc2\xa0/u, ' ')
end
end
def replace_nbsp_ref(str)
str.gsub('&#xA0;',' ').gsub('&nbsp;', ' ')
end
def error_message
"Could not find link with text or title or id #{@value.inspect}"
end
end
def find_link(text_or_title_or_id) #:nodoc:
LinkLocator.new(@session, dom, text_or_title_or_id).locate!
end
end
end

View File

@ -0,0 +1,20 @@
module Webrat
module Locators
class Locator # :nodoc:
def initialize(session, dom, value, *field_types)
@session = session
@dom = dom
@value = value
@field_types = field_types
end
def locate!
locate || raise(NotFoundError.new(error_message))
end
end
end
end

View File

@ -0,0 +1,59 @@
require "webrat/core_extensions/detect_mapped"
require "webrat/core/locators/locator"
module Webrat
module Locators
class SelectOptionLocator < Locator # :nodoc:
def initialize(session, dom, option_text, id_or_name_or_label)
@session = session
@dom = dom
@option_text = option_text
@id_or_name_or_label = id_or_name_or_label
end
def locate
if @id_or_name_or_label
field = FieldLocator.new(@session, @dom, @id_or_name_or_label, SelectField).locate!
field.options.detect do |o|
if @option_text.is_a?(Regexp)
o.element.inner_text =~ @option_text
else
o.inner_text == @option_text.to_s
end
end
else
option_element = option_elements.detect do |o|
if @option_text.is_a?(Regexp)
o.inner_text =~ @option_text
else
o.inner_text == @option_text.to_s
end
end
SelectOption.load(@session, option_element)
end
end
def option_elements
@dom.xpath(*SelectOption.xpath_search)
end
def error_message
if @id_or_name_or_label
"The '#{@option_text}' option was not found in the #{@id_or_name_or_label.inspect} select box"
else
"Could not find option #{@option_text.inspect}"
end
end
end
def select_option(option_text, id_or_name_or_label = nil) #:nodoc:
SelectOptionLocator.new(@session, dom, option_text, id_or_name_or_label).locate!
end
end
end

View File

@ -1,25 +1,23 @@
require "logger"
module Webrat
module Logging #:nodoc:
def warn_log(message) # :nodoc:
return unless logger
logger.warn message
end
def debug_log(message) # :nodoc:
return unless logger
logger.debug message
end
def logger # :nodoc:
if defined? RAILS_DEFAULT_LOGGER
RAILS_DEFAULT_LOGGER
elsif defined? Merb
Merb.logger
case Webrat.configuration.mode
when :rails
defined?(RAILS_DEFAULT_LOGGER) ? RAILS_DEFAULT_LOGGER : nil
when :merb
::Merb.logger
else
nil
@logger ||= ::Logger.new("webrat.log")
end
end
end
end
end

View File

@ -1,76 +1,39 @@
module Webrat
module Matchers
class HasContent #:nodoc:
def initialize(content)
@content = content
end
def matches?(stringlike)
if defined?(Nokogiri::XML)
matches_nokogiri?(stringlike)
else
matches_rexml?(stringlike)
end
end
def matches_rexml?(stringlike)
@document = rexml_document(stringlike)
@document = Webrat::XML.document(stringlike)
@element = @document.inner_text
case @content
when String
@element.include?(@content)
@element.gsub(/\s+/, ' ').include?(@content)
when Regexp
@element.match(@content)
end
end
def matches_nokogiri?(stringlike)
@document = Webrat.nokogiri_document(stringlike)
@element = @document.inner_text
case @content
when String
@element.include?(@content)
when Regexp
@element.match(@content)
end
end
def rexml_document(stringlike)
stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
case stringlike
when REXML::Document
stringlike.root
when REXML::Node
stringlike
when StringIO, String
begin
REXML::Document.new(stringlike.to_s).root
rescue REXML::ParseException => e
if e.message.include?("second root element")
REXML::Document.new("<fake-root-element>#{stringlike}</fake-root-element>").root
else
raise e
end
end
end
end
# ==== Returns
# String:: The failure message.
def failure_message
"expected the following element's content to #{content_message}:\n#{@element}"
"expected the following element's content to #{content_message}:\n#{squeeze_space(@element)}"
end
# ==== Returns
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected the following element's content to not #{content_message}:\n#{@element}"
"expected the following element's content to not #{content_message}:\n#{squeeze_space(@element)}"
end
def squeeze_space(inner_text)
inner_text.gsub(/^\s*$/, "").squeeze("\n")
end
def content_message
case @content
when String
@ -80,15 +43,26 @@ module Webrat
end
end
end
# Matches the contents of an HTML document with
# whatever string is supplied
#
# ---
# @api public
def contain(content)
HasContent.new(content)
end
# Asserts that the body of the response contain
# the supplied string or regexp
def assert_contain(content)
hc = HasContent.new(content)
assert hc.matches?(response_body), hc.failure_message
end
# Asserts that the body of the response
# does not contain the supplied string or regepx
def assert_not_contain(content)
hc = HasContent.new(content)
assert !hc.matches?(response_body), hc.negative_failure_message
end
end
end
end

View File

@ -1,26 +1,48 @@
require "webrat/core/matchers/have_xpath"
module Webrat
module Matchers
class HaveSelector < HaveXpath #:nodoc:
class HaveSelector < HaveXpath #:nodoc:
# ==== Returns
# String:: The failure message.
def failure_message
"expected following text to match selector #{@expected}:\n#{@document}"
"expected following output to contain a #{tag_inspect} tag:\n#{@document}"
end
# ==== Returns
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected following text to not match selector #{@expected}:\n#{@document}"
"expected following output to omit a #{tag_inspect}:\n#{@document}"
end
def tag_inspect
options = @options.dup
count = options.delete(:count)
content = options.delete(:content)
html = "<#{@expected}"
options.each do |k,v|
html << " #{k}='#{v}'"
end
if content
html << ">#{content}</#{@expected}>"
else
html << "/>"
end
html
end
def query
Nokogiri::CSS::Parser.parse(*super).map { |ast| ast.to_xpath }
Nokogiri::CSS.parse(@expected.to_s).map do |ast|
ast.to_xpath
end.first
end
end
# Matches HTML content against a CSS 3 selector.
#
# ==== Parameters
@ -28,12 +50,25 @@ module Webrat
#
# ==== Returns
# HaveSelector:: A new have selector matcher.
# ---
# @api public
def have_selector(expected, &block)
HaveSelector.new(expected, &block)
def have_selector(name, attributes = {}, &block)
HaveSelector.new(name, attributes, &block)
end
alias_method :match_selector, :have_selector
# Asserts that the body of the response contains
# the supplied selector
def assert_have_selector(name, attributes = {}, &block)
matcher = HaveSelector.new(name, attributes, &block)
assert matcher.matches?(response_body), matcher.failure_message
end
# Asserts that the body of the response
# does not contain the supplied string or regepx
def assert_have_no_selector(name, attributes = {}, &block)
matcher = HaveSelector.new(name, attributes, &block)
assert !matcher.matches?(response_body), matcher.negative_failure_message
end
end
end
end

View File

@ -1,58 +1,21 @@
require "webrat/core/matchers/have_selector"
module Webrat
module HaveTagMatcher
class HaveTag < ::Webrat::Matchers::HaveSelector #:nodoc:
# ==== Returns
# String:: The failure message.
def failure_message
"expected following output to contain a #{tag_inspect} tag:\n#{@document}"
end
# ==== Returns
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected following output to omit a #{tag_inspect}:\n#{@document}"
end
def tag_inspect
options = @expected.last.dup
content = options.delete(:content)
html = "<#{@expected.first}"
options.each do |k,v|
html << " #{k}='#{v}'"
end
if content
html << ">#{content}</#{@expected.first}>"
else
html << "/>"
end
html
end
def query
options = @expected.last.dup
selector = @expected.first.to_s
selector << ":contains('#{options.delete(:content)}')" if options[:content]
options.each do |key, value|
selector << "[#{key}='#{value}']"
end
Nokogiri::CSS::Parser.parse(selector).map { |ast| ast.to_xpath }
end
def have_tag(*args, &block)
have_selector(*args, &block)
end
def have_tag(name, attributes = {}, &block)
HaveTag.new([name, attributes], &block)
end
alias_method :match_tag, :have_tag
def assert_have_tag(*args, &block)
assert_have_selector(*args, &block)
end
def assert_have_no_tag(*args, &block)
assert_have_no_selector(*args, &block)
end
end
end
end

View File

@ -1,74 +1,73 @@
require "webrat/core/xml"
module Webrat
module Matchers
class HaveXpath #:nodoc:
def initialize(expected, &block)
def initialize(expected, options = {}, &block)
@expected = expected
@options = options
@block = block
end
def matches?(stringlike)
if defined?(Nokogiri::XML)
matches_nokogiri?(stringlike)
def matches?(stringlike, &block)
@block ||= block
matched = matches(stringlike)
@block.call(matched) if @block
if @options[:count]
matched.size == @options[:count].to_i
else
matches_rexml?(stringlike)
matched.any?
end
end
def matches_rexml?(stringlike)
@query = query
@document = rexml_document(stringlike)
matched = @query.map do |q|
if @document.is_a?(Array)
@document.map { |d| REXML::XPath.match(d, q) }
else
REXML::XPath.match(@document, q)
end
end.flatten.compact
matched.any? && (!@block || @block.call(matched))
def matches(stringlike)
nokogiri_matches(stringlike)
end
def matches_nokogiri?(stringlike)
def nokogiri_matches(stringlike)
if Nokogiri::XML::NodeSet === stringlike
@query = query.map { |q| q.gsub(%r'//', './') }
@query = query.gsub(%r'^//', './/')
else
@query = query
end
@document = Webrat.nokogiri_document(stringlike)
matched = @document.xpath(*@query)
matched.any? && (!@block || @block.call(matched))
add_options_conditions_to(@query)
@document = Webrat::XML.document(stringlike)
@document.xpath(*@query)
end
def rexml_document(stringlike)
stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
case stringlike
when REXML::Document
stringlike.root
when REXML::Node, Array
@query = query.map { |q| q.gsub(%r'//', './') }
stringlike
else
begin
REXML::Document.new(stringlike.to_s).root
rescue REXML::ParseException => e
if e.message.include?("second root element")
REXML::Document.new("<fake-root-element>#{stringlike}</fake-root-element>").root
else
raise e
end
end
def add_options_conditions_to(query)
add_attributes_conditions_to(query)
add_content_condition_to(query)
end
def add_attributes_conditions_to(query)
attribute_conditions = []
@options.each do |key, value|
next if [:content, :count].include?(key)
attribute_conditions << "@#{key} = #{xpath_escape(value)}"
end
if attribute_conditions.any?
query << "[#{attribute_conditions.join(' and ')}]"
end
end
def query
[@expected].flatten.compact
def add_content_condition_to(query)
if @options[:content]
query << "[contains(., #{xpath_escape(@options[:content])})]"
end
end
def query
@expected
end
# ==== Returns
# String:: The failure message.
def failure_message
@ -79,9 +78,26 @@ module Webrat
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected following text to not match xpath #{@expected}:\n#{@document}"
end
end
protected
def xpath_escape(string)
if string.include?("'") && string.include?('"')
parts = string.split("'").map do |part|
"'#{part}'"
end
"concat(" + parts.join(", \"'\", ") + ")"
elsif string.include?("'")
"\"#{string}\""
else
"'#{string}'"
end
end
end
# Matches HTML content against an XPath query
#
# ==== Parameters
@ -89,12 +105,20 @@ module Webrat
#
# ==== Returns
# HaveXpath:: A new have xpath matcher.
# ---
# @api public
def have_xpath(expected, &block)
HaveXpath.new(expected, &block)
def have_xpath(expected, options = {}, &block)
HaveXpath.new(expected, options, &block)
end
alias_method :match_xpath, :have_xpath
def assert_have_xpath(expected, options = {}, &block)
hs = HaveXpath.new(expected, options, &block)
assert hs.matches?(response_body), hs.failure_message
end
def assert_have_no_xpath(expected, options = {}, &block)
hs = HaveXpath.new(expected, options, &block)
assert !hs.matches?(response_body), hs.negative_failure_message
end
end
end
end

View File

@ -3,15 +3,26 @@ module Webrat
def self.delegate_to_session(*meths)
meths.each do |meth|
self.class_eval <<-RUBY
self.class_eval(<<-RUBY, __FILE__, __LINE__)
def #{meth}(*args, &blk)
@_webrat_session ||= ::Webrat::MerbSession.new
@_webrat_session.#{meth}(*args, &blk)
webrat_session.#{meth}(*args, &blk)
end
RUBY
end
end
def webrat
webrat_session
end
def webrat_session
@_webrat_session ||= begin
session = Webrat.session_class.new
session.adapter = Webrat.adapter_class.new(self) if session.respond_to?(:adapter=)
session
end
end
# all of these methods delegate to the @session, which should
# be created transparently.
#
@ -23,22 +34,31 @@ module Webrat
:within,
:header, :http_accept, :basic_auth,
:save_and_open_page,
:fill_in,
:check,
:uncheck,
:choose,
:select,
:attach_file,
:cookies,
:response,
:fills_in, :fill_in,
:checks, :check,
:unchecks, :uncheck,
:chooses, :choose,
:selects, :select,
:unselects, :unselect,
:attaches_file, :attach_file,
:current_page,
:current_url,
:click_link,
:click_area,
:click_button,
:clicks_link, :click_link,
:clicks_area, :click_area,
:clicks_button, :click_button,
:reload, :reloads,
:clicks_link_within,
:field_labeled
:clicks_link_within, :click_link_within,
:field_labeled,
:select_option,
:set_hidden_field, :submit_form,
:request_page, :current_dom,
:response_body,
:selects_date, :selects_time, :selects_datetime,
:select_date, :select_time, :select_datetime,
:field_by_xpath,
:field_with_id,
:selenium,
:simulate, :automate,
:field_named
end
end
end

View File

@ -1,29 +1,18 @@
module Webrat
module MIME
def self.mime_type(string_or_symbol)
if string_or_symbol.is_a?(String)
string_or_symbol
else
case string_or_symbol
when :text then "text/plain"
when :html then "text/html"
when :js then "text/javascript"
when :css then "text/css"
when :ics then "text/calendar"
when :csv then "text/csv"
when :xml then "application/xml"
when :rss then "application/rss+xml"
when :atom then "application/atom+xml"
when :yaml then "application/x-yaml"
when :multipart_form then "multipart/form-data"
when :url_encoded_form then "application/x-www-form-urlencoded"
when :json then "application/json"
else
raise ArgumentError.new("Invalid Mime type: #{string_or_symbol.inspect}")
end
end
module Webrat #:nodoc:
module MIME #:nodoc:
MIME_TYPES = Rack::Mime::MIME_TYPES.dup.merge(
".multipart_form" => "multipart/form-data",
".url_encoded_form" => "application/x-www-form-urlencoded"
).freeze
def mime_type(type)
return type if type.nil? || type.to_s.include?("/")
type = ".#{type}" unless type.to_s[0] == ?.
MIME_TYPES.fetch(type) { |invalid_type|
raise ArgumentError.new("Invalid Mime type: #{invalid_type}")
}
end
module_function :mime_type
end
end
end

View File

@ -1,44 +0,0 @@
require "webrat/core_extensions/meta_class"
module Webrat
def self.nokogiri_document(stringlike) #:nodoc:
return stringlike.dom if stringlike.respond_to?(:dom)
if Nokogiri::HTML::Document === stringlike
stringlike
elsif Nokogiri::XML::NodeSet === stringlike
stringlike
elsif StringIO === stringlike
Nokogiri::HTML(stringlike.string)
elsif stringlike.respond_to?(:body)
Nokogiri::HTML(stringlike.body.to_s)
else
Nokogiri::HTML(stringlike.to_s)
end
end
def self.define_dom_method(object, dom) #:nodoc:
object.meta_class.send(:define_method, :dom) do
dom
end
end
end
module Nokogiri
module CSS
class XPathVisitor
def visit_pseudo_class_text(node) #:nodoc:
"@type='text'"
end
def visit_pseudo_class_password(node) #:nodoc:
"@type='password'"
end
end
end
end

View File

@ -0,0 +1,28 @@
module Webrat
module SaveAndOpenPage
# Saves the page out to RAILS_ROOT/tmp/ and opens it in the default
# web browser if on OS X. Useful for debugging.
#
# Example:
# save_and_open_page
def save_and_open_page
return unless File.exist?(Webrat.configuration.saved_pages_dir)
filename = "#{Webrat.configuration.saved_pages_dir}/webrat-#{Time.now.to_i}.html"
File.open(filename, "w") do |f|
f.write response_body
end
open_in_browser(filename)
end
def open_in_browser(path) # :nodoc
require "launchy"
Launchy::Browser.run(path)
rescue LoadError
warn "Sorry, you need to install launchy to open pages: `gem install launchy`"
end
end
end

View File

@ -1,32 +1,42 @@
require "nokogiri"
require "webrat/core/form"
require "webrat/core/elements/form"
require "webrat/core/locators"
require "webrat/core_extensions/deprecate"
module Webrat
# An HTML element (link, button, field, etc.) that Webrat expected was not found on the page
class NotFoundError < WebratError
end
class Scope
include Logging
include Flunk
include Locators
def self.from_page(session, response, response_body) #:nodoc:
new(session) do
@response = response
@response_body = response_body
end
end
def self.from_scope(session, scope, selector) #:nodoc:
new(session) do
@scope = scope
@selector = selector
end
end
attr_reader :session
def initialize(session, &block) #:nodoc:
@selector, @dom = nil
@session = session
instance_eval(&block) if block_given?
if @selector && scoped_dom.nil?
raise Webrat::NotFoundError.new("The scope was not found on the page: #{@selector.inspect}")
end
end
# Verifies an input field or textarea exists on the current page, and stores a value for
# it which will be sent when the form is submitted.
#
@ -43,8 +53,18 @@ module Webrat
field.set(options[:with])
end
alias_method :fills_in, :fill_in
webrat_deprecate :fills_in, :fill_in
# Verifies that a hidden field exists on the current page and sets
# the value to that given by the <tt>:to</tt> option.
#
# Example:
# set_hidden_field 'user_id', :to => 1
def set_hidden_field(field_locator, options = {})
field = locate_field(field_locator, HiddenField)
field.set(options[:to])
end
# Verifies that an input checkbox exists on the current page and marks it
# as checked, so that the value will be submitted with the form.
#
@ -54,8 +74,8 @@ module Webrat
locate_field(field_locator, CheckboxField).check
end
alias_method :checks, :check
webrat_deprecate :checks, :check
# Verifies that an input checkbox exists on the current page and marks it
# as unchecked, so that the value will not be submitted with the form.
#
@ -65,8 +85,8 @@ module Webrat
locate_field(field_locator, CheckboxField).uncheck
end
alias_method :unchecks, :uncheck
webrat_deprecate :unchecks, :uncheck
# Verifies that an input radio button exists on the current page and marks it
# as checked, so that the value will be submitted with the form.
#
@ -76,46 +96,162 @@ module Webrat
locate_field(field_locator, RadioField).choose
end
alias_method :chooses, :choose
webrat_deprecate :chooses, :choose
# Verifies that a an option element exists on the current page with the specified
# text. You can optionally restrict the search to a specific select list by
# assigning <tt>options[:from]</tt> the value of the select list's name or
# a label. Stores the option's value to be sent when the form is submitted.
#
# Examples:
# selects "January"
# selects "February", :from => "event_month"
# selects "February", :from => "Event Month"
def selects(option_text, options = {})
find_select_option(option_text, options[:from]).choose
# select "January"
# select "February", :from => "event_month"
# select "February", :from => "Event Month"
def select(option_text, options = {})
select_option(option_text, options[:from]).choose
end
alias_method :select, :selects
webrat_deprecate :selects, :select
# Verifies that a an option element exists on the current page with the specified
# text. You can optionally restrict the search to a specific select list by
# assigning <tt>options[:from]</tt> the value of the select list's name or
# a label. Remove the option's value before the form is submitted.
#
# Examples:
# unselect "January"
# unselect "February", :from => "event_month"
# unselect "February", :from => "Event Month"
def unselect(option_text, options={})
select_option(option_text, options[:from]).unchoose
end
webrat_deprecate :unselects, :unselect
DATE_TIME_SUFFIXES = {
:year => '1i',
:month => '2i',
:day => '3i',
:hour => '4i',
:minute => '5i'
}
# Verifies that date elements (year, month, day) exist on the current page
# with the specified values. You can optionally restrict the search to a specific
# date's elements by assigning <tt>options[:from]</tt> the value of the date's
# label. Selects all the date elements with date provided. The date provided may
# be a string or a Date/Time object.
#
# Rail's convention is used for detecting the date elements. All elements
# are assumed to have a shared prefix. You may also specify the prefix
# by assigning <tt>options[:id_prefix]</tt>.
#
# Examples:
# select_date "January 23, 2004"
# select_date "April 26, 1982", :from => "Birthday"
# select_date Date.parse("December 25, 2000"), :from => "Event"
# select_date "April 26, 1982", :id_prefix => 'birthday'
def select_date(date_to_select, options ={})
date = date_to_select.is_a?(Date) || date_to_select.is_a?(Time) ?
date_to_select : Date.parse(date_to_select)
id_prefix = locate_id_prefix(options) do
year_field = FieldByIdLocator.new(@session, dom, /(.*?)_#{DATE_TIME_SUFFIXES[:year]}$/).locate
raise NotFoundError.new("No date fields were found") unless year_field && year_field.id =~ /(.*?)_1i/
$1
end
select date.year, :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:year]}"
select date.strftime('%B'), :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:month]}"
select date.day, :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:day]}"
end
webrat_deprecate :selects_date, :select_date
# Verifies that time elements (hour, minute) exist on the current page
# with the specified values. You can optionally restrict the search to a specific
# time's elements by assigning <tt>options[:from]</tt> the value of the time's
# label. Selects all the time elements with date provided. The time provided may
# be a string or a Time object.
#
# Rail's convention is used for detecting the time elements. All elements are
# assumed to have a shared prefix. You may specify the prefix by assigning
# <tt>options[:id_prefix]</tt>.
#
# Note: Just like Rails' time_select helper this assumes the form is using
# 24 hour select boxes, and not 12 hours with AM/PM.
#
# Examples:
# select_time "9:30"
# select_date "3:30PM", :from => "Party Time"
# select_date Time.parse("10:00PM"), :from => "Event"
# select_date "10:30AM", :id_prefix => 'meeting'
def select_time(time_to_select, options ={})
time = time_to_select.is_a?(Time) ? time_to_select : Time.parse(time_to_select)
id_prefix = locate_id_prefix(options) do
hour_field = FieldByIdLocator.new(@session, dom, /(.*?)_#{DATE_TIME_SUFFIXES[:hour]}$/).locate
raise NotFoundError.new("No time fields were found") unless hour_field && hour_field.id =~ /(.*?)_4i/
$1
end
select time.hour.to_s.rjust(2,'0'), :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:hour]}"
select time.min.to_s.rjust(2,'0'), :from => "#{id_prefix}_#{DATE_TIME_SUFFIXES[:minute]}"
end
webrat_deprecate :selects_time, :select_time
# Verifies and selects all the date and time elements on the current page.
# See #select_time and #select_date for more details and available options.
#
# Examples:
# select_datetime "January 23, 2004 10:30AM"
# select_datetime "April 26, 1982 7:00PM", :from => "Birthday"
# select_datetime Time.parse("December 25, 2000 15:30"), :from => "Event"
# select_datetime "April 26, 1982 5:50PM", :id_prefix => 'birthday'
def select_datetime(time_to_select, options ={})
time = time_to_select.is_a?(Time) ? time_to_select : Time.parse(time_to_select)
options[:id_prefix] ||= (options[:from] ? FieldByIdLocator.new(@session, dom, options[:from]).locate : nil)
select_date time, options
select_time time, options
end
webrat_deprecate :selects_datetime, :select_datetime
# Verifies that an input file field exists on the current page and sets
# its value to the given +file+, so that the file will be uploaded
# along with the form. An optional <tt>content_type</tt> may be given.
#
# Example:
# attaches_file "Resume", "/path/to/the/resume.txt"
# attaches_file "Photo", "/path/to/the/image.png", "image/png"
# attach_file "Resume", "/path/to/the/resume.txt"
# attach_file "Photo", "/path/to/the/image.png", "image/png"
def attach_file(field_locator, path, content_type = nil)
locate_field(field_locator, FileField).set(path, content_type)
end
alias_method :attaches_file, :attach_file
webrat_deprecate :attaches_file, :attach_file
# Issues a request for the URL pointed to by an <tt>area</tt> tag
# on the current page, follows any redirects, and verifies the
# final page load was successful.
#
# The area used is the first area whose title or id contains the
# given +area_name+ (case is ignored).
#
# Example:
# click_area 'Australia'
def click_area(area_name)
find_area(area_name).click
end
alias_method :clicks_area, :click_area
webrat_deprecate :clicks_area, :click_area
# Issues a request for the URL pointed to by a link on the current page,
# follows any redirects, and verifies the final page load was successful.
#
# click_link has very basic support for detecting Rails-generated
#
# click_link has very basic support for detecting Rails-generated
# JavaScript onclick handlers for PUT, POST and DELETE links, as well as
# CSRF authenticity tokens if they are present.
#
@ -123,19 +259,25 @@ module Webrat
#
# Passing a :method in the options hash overrides the HTTP method used
# for making the link request
#
#
# It will try to find links by (in order of precedence):
# innerHTML, with simple &nbsp; handling
# title
# id
#
# innerHTML and title are matchable by text subtring or Regexp
# id is matchable by full text equality or Regexp
#
# Example:
# click_link "Sign up"
#
# click_link "Sign up", :javascript => false
#
# click_link "Sign up", :method => :put
def click_link(link_text, options = {})
find_link(link_text).click(options)
def click_link(text_or_title_or_id, options = {})
find_link(text_or_title_or_id).click(options)
end
alias_method :clicks_link, :click_link
webrat_deprecate :clicks_link, :click_link
# Verifies that a submit button exists for the form, then submits the form, follows
# any redirects, and verifies the final page was successful.
#
@ -149,33 +291,51 @@ module Webrat
find_button(value).click
end
alias_method :clicks_button, :click_button
webrat_deprecate :clicks_button, :click_button
# Submit the form with the given id.
#
# Note that +click_button+ is usually preferrable for simulating
# form submissions, as you may specify part of the button text
# rather than the form id.
#
# Example:
# submit_form 'login'
def submit_form(id)
FormLocator.new(@session, dom, id).locate.submit
end
def dom # :nodoc:
return @dom if @dom
if @selector
@dom = scoped_dom
else
@dom = page_dom
end
return @dom
end
protected
def page_dom #:nodoc:
return @response.dom if @response.respond_to?(:dom)
dom = Webrat.nokogiri_document(@response_body)
Webrat.define_dom_method(@response, dom)
if @session.xml_content_type?
dom = Webrat::XML.xml_document(@response_body)
else
dom = Webrat::XML.html_document(@response_body)
end
Webrat::XML.define_dom_method(@response, dom)
return dom
end
def scoped_dom #:nodoc:
Webrat.nokogiri_document(@scope.dom.search(@selector).first.to_html)
def scoped_dom
@scope.dom.css(@selector).first
end
def locate_field(field_locator, *field_types) #:nodoc:
if field_locator.is_a?(Field)
field_locator
@ -183,26 +343,24 @@ module Webrat
field(field_locator, *field_types)
end
end
def areas #:nodoc:
dom.search("area").map do |element|
Area.new(@session, element)
def locate_id_prefix(options, &location_strategy) #:nodoc:
return options[:id_prefix] if options[:id_prefix]
if options[:from]
if (label = LabelLocator.new(@session, dom, options[:from]).locate)
label.for_id
else
raise NotFoundError.new("Could not find the label with text #{options[:from]}")
end
else
yield
end
end
def links #:nodoc:
dom.search("a[@href]").map do |link_element|
Link.new(@session, link_element)
end
end
def forms #:nodoc:
return @forms if @forms
@forms = dom.search("form").map do |form_element|
Form.new(@session, form_element)
end
@forms ||= Form.load_all(@session, dom)
end
end
end
end

View File

@ -1,29 +0,0 @@
module Webrat
class SelectOption #:nodoc:
def initialize(select, element)
@select = select
@element = element
end
def matches_text?(text)
if text.is_a?(Regexp)
@element.inner_html =~ text
else
@element.inner_html == text.to_s
end
end
def choose
@select.raise_error_if_disabled
@select.set(value)
end
protected
def value
@element["value"] || @element.inner_html
end
end
end

View File

@ -2,59 +2,96 @@ require "forwardable"
require "ostruct"
require "webrat/core/mime"
require "webrat/core/save_and_open_page"
module Webrat
# A page load or form submission returned an unsuccessful response code (500-599)
class PageLoadError < WebratError
end
class InfiniteRedirectError < WebratError
end
def self.session_class
if Webrat.configuration.mode == :selenium
SeleniumSession
else
Session
end
end
def self.adapter_class
case Webrat.configuration.mode
when :rails
RailsAdapter
when :merb
MerbAdapter
when :rack
RackAdapter
when :rack_test
warn("The :rack_test mode is deprecated. Please use :rack instead")
require "webrat/rack"
RackAdapter
when :sinatra
warn("The :sinatra mode is deprecated. Please use :rack instead")
SinatraAdapter
when :mechanize
MechanizeAdapter
else
raise WebratError.new(<<-STR)
Unknown Webrat mode: #{Webrat.configuration.mode.inspect}
Please ensure you have a Webrat configuration block that specifies a mode
in your test_helper.rb, spec_helper.rb, or env.rb (for Cucumber).
This configure block supercedes the need to require "webrat/<framework>".
For example:
Webrat.configure do |config|
config.mode = :rails
end
STR
end
end
class Session
extend Forwardable
include Logging
include Flunk
include SaveAndOpenPage
attr_accessor :adapter
attr_reader :current_url
def initialize #:nodoc:
attr_reader :elements
def_delegators :@adapter, :response, :response_code, :response_body, :response_headers,
:response_body=, :response_code=,
:get, :post, :put, :delete
def initialize(adapter = nil)
@adapter = adapter
@http_method = :get
@data = {}
@default_headers = {}
@custom_headers = {}
@current_url = nil
reset
end
# Saves the page out to RAILS_ROOT/tmp/ and opens it in the default
# web browser if on OS X. Useful for debugging.
#
# Example:
# save_and_open_page
def save_and_open_page
return unless File.exist?(saved_page_dir)
filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.html"
File.open(filename, "w") do |f|
f.write rewrite_css_and_image_references(response_body)
end
open_in_browser(filename)
end
def current_dom #:nodoc:
current_scope.dom
end
# For backwards compatibility -- removing in 1.0
def current_page #:nodoc:
warn "current_page is deprecated and will be going away in the next release. Use current_url instead."
page = OpenStruct.new
page.url = @current_url
page.http_method = @http_method
page.data = @data
page
end
def doc_root #:nodoc:
nil
end
def saved_page_dir #:nodoc:
File.expand_path(".")
end
def header(key, value)
@custom_headers[key] = value
@ -63,9 +100,9 @@ module Webrat
def http_accept(mime_type)
header('Accept', Webrat::MIME.mime_type(mime_type))
end
def basic_auth(user, pass)
encoded_login = ["#{user}:#{pass}"].pack("m*")
encoded_login = ["#{user}:#{pass}"].pack("m*").gsub(/\n/, '')
header('HTTP_AUTHORIZATION', "Basic #{encoded_login}")
end
@ -78,50 +115,82 @@ module Webrat
h['HTTP_REFERER'] = @current_url if @current_url
debug_log "REQUESTING PAGE: #{http_method.to_s.upcase} #{url} with #{data.inspect} and HTTP headers #{h.inspect}"
if h.empty?
send "#{http_method}", url, data || {}
else
send "#{http_method}", url, data || {}, h
end
save_and_open_page if exception_caught?
flunk("Page load was not successful (Code: #{response_code.inspect}):\n#{formatted_error}") unless success_code?
@_scopes = nil
@_page_scope = nil
process_request(http_method, url, data, h)
save_and_open_page if exception_caught? && Webrat.configuration.open_error_files?
raise PageLoadError.new("Page load was not successful (Code: #{response_code.inspect}):\n#{formatted_error}") unless success_code?
reset
@current_url = url
@http_method = http_method
@data = data
if internal_redirect?
check_for_infinite_redirects
request_page(response_location, :get, {})
end
return response
end
def check_for_infinite_redirects
if current_url == response_location
@_identical_redirect_count ||= 0
@_identical_redirect_count += 1
end
if infinite_redirect_limit_exceeded?
raise InfiniteRedirectError.new("#{Webrat.configuration.infinite_redirect_limit} redirects to the same URL (#{current_url.inspect})")
end
end
def infinite_redirect_limit_exceeded?
Webrat.configuration.infinite_redirect_limit &&
(@_identical_redirect_count || 0) > Webrat.configuration.infinite_redirect_limit
end
def success_code? #:nodoc:
(200..499).include?(response_code)
end
def redirect? #:nodoc:
[301, 302, 303, 307].include?(response_code)
end
def internal_redirect?
return false unless redirect?
#should keep internal_redirects if the subdomain changes
current_host_domain = current_host.split('.')[-2..-1].join('.') rescue current_host
response_location_host_domain = response_location_host.split('.')[-2..-1].join('.') rescue response_location_host
current_host_domain == response_location_host_domain
end
#easy helper to pull out where we were redirected to
def redirected_to
redirect? ? response_location : nil
end
def exception_caught? #:nodoc:
response_body =~ /Exception caught/
end
def current_scope #:nodoc:
scopes.last || page_scope
end
# Reloads the last page requested. Note that this will resubmit forms
# and their data.
#
# Example:
# reloads
def reloads
def reload
request_page(@current_url, @http_method, @data)
end
alias_method :reload, :reloads
webrat_deprecate :reloads, :reload
# Works like click_link, but only looks for the link text within a given selector
#
#
# Example:
# click_link_within "#user_12", "Vote"
def click_link_within(selector, link_text)
@ -130,15 +199,15 @@ module Webrat
end
end
alias_method :clicks_link_within, :click_link_within
webrat_deprecate :clicks_link_within, :click_link_within
def within(selector)
scopes.push(Scope.from_scope(self, current_scope, selector))
ret = yield(current_scope)
scopes.pop
return ret
end
# Issues a GET request for a page, follows any redirects, and verifies the final page
# load was successful.
#
@ -147,17 +216,8 @@ module Webrat
def visit(url = nil, http_method = :get, data = {})
request_page(url, http_method, data)
end
alias_method :visits, :visit
def open_in_browser(path) #:nodoc
`open #{path}`
end
def rewrite_css_and_image_references(response_html) #:nodoc
return response_html unless doc_root
response_html.gsub(/"\/(stylesheets|images)/, doc_root + '/\1')
end
webrat_deprecate :visits, :visit
# Subclasses can override this to show error messages without html
def formatted_error #:nodoc:
@ -171,18 +231,73 @@ module Webrat
def page_scope #:nodoc:
@_page_scope ||= Scope.from_page(self, response, response_body)
end
def dom
page_scope.dom
end
def xml_content_type?
false
end
def simulate
return if Webrat.configuration.mode == :selenium
yield
end
def automate
return unless Webrat.configuration.mode == :selenium
yield
end
def_delegators :current_scope, :fill_in, :fills_in
def_delegators :current_scope, :set_hidden_field
def_delegators :current_scope, :submit_form
def_delegators :current_scope, :check, :checks
def_delegators :current_scope, :uncheck, :unchecks
def_delegators :current_scope, :choose, :chooses
def_delegators :current_scope, :select, :selects
def_delegators :current_scope, :unselect, :unselects
def_delegators :current_scope, :select_datetime, :selects_datetime
def_delegators :current_scope, :select_date, :selects_date
def_delegators :current_scope, :select_time, :selects_time
def_delegators :current_scope, :attach_file, :attaches_file
def_delegators :current_scope, :click_area, :clicks_area
def_delegators :current_scope, :click_link, :clicks_link
def_delegators :current_scope, :click_button, :clicks_button
def_delegators :current_scope, :should_see
def_delegators :current_scope, :should_not_see
def_delegators :current_scope, :field_labeled
def_delegators :current_scope, :field_by_xpath
def_delegators :current_scope, :field_with_id
def_delegators :current_scope, :select_option
def_delegators :current_scope, :field_named
private
def process_request(http_method, url, data, headers)
if headers.empty?
send "#{http_method}", url, data || {}
else
send "#{http_method}", url, data || {}, headers
end
end
def response_location
response_headers['Location']
end
def current_host
URI.parse(current_url).host || @custom_headers["Host"] || "www.example.com"
end
def response_location_host
URI.parse(response_location).host || "www.example.com"
end
def reset
@elements = {}
@_scopes = nil
@_page_scope = nil
end
end
end

72
lib/webrat/core/xml.rb Normal file
View File

@ -0,0 +1,72 @@
require "webrat/core_extensions/meta_class"
module Webrat #:nodoc:
module XML #:nodoc:
def self.document(stringlike) #:nodoc:
return stringlike.dom if stringlike.respond_to?(:dom)
if Nokogiri::HTML::Document === stringlike
stringlike
elsif Nokogiri::XML::NodeSet === stringlike
stringlike
elsif stringlike.respond_to?(:body)
Nokogiri::HTML(stringlike.body.to_s)
else
Nokogiri::HTML(stringlike.to_s)
end
end
def self.html_document(stringlike) #:nodoc:
return stringlike.dom if stringlike.respond_to?(:dom)
if Nokogiri::HTML::Document === stringlike
stringlike
elsif Nokogiri::XML::NodeSet === stringlike
stringlike
elsif stringlike.respond_to?(:body)
Nokogiri::HTML(stringlike.body.to_s)
else
Nokogiri::HTML(stringlike.to_s)
end
end
def self.xml_document(stringlike) #:nodoc:
return stringlike.dom if stringlike.respond_to?(:dom)
if Nokogiri::HTML::Document === stringlike
stringlike
elsif Nokogiri::XML::NodeSet === stringlike
stringlike
elsif stringlike.respond_to?(:body)
Nokogiri::XML(stringlike.body.to_s)
else
Nokogiri::XML(stringlike.to_s)
end
end
def self.define_dom_method(object, dom) #:nodoc:
object.meta_class.send(:define_method, :dom) do
dom
end
end
end
end
module Nokogiri #:nodoc:
module CSS #:nodoc:
class XPathVisitor #:nodoc:
def visit_pseudo_class_text(node) #:nodoc:
"@type='text'"
end
def visit_pseudo_class_password(node) #:nodoc:
"@type='password'"
end
end
end
end

View File

@ -12,7 +12,7 @@ class Object #:nodoc:
def blank?
respond_to?(:empty?) ? empty? : !self
end
# An object is present if it's not blank.
def present?
!blank?

View File

@ -1,8 +1,8 @@
class Module #:nodoc:
def deprecate(old_method_name, new_method_name)
def webrat_deprecate(old_method_name, new_method_name)
define_method old_method_name do |*args|
warn "#{old_method_name} is deprecated. Use #{new_method_name} instead."
__send__(new_method_name, *args)
end
end
end
end

View File

@ -1,12 +1,12 @@
class Array #:nodoc:
def detect_mapped
each do |element|
result = yield element
return result if result
end
return nil
end
end
end

View File

@ -1,131 +0,0 @@
# This class has dubious semantics and we only have it so that
# people can write params[:key] instead of params['key']
# and they get the same value for both keys.
class HashWithIndifferentAccess < Hash #:nodoc:
def initialize(constructor = {})
if constructor.is_a?(Hash)
super()
update(constructor)
else
super(constructor)
end
end
def default(key = nil)
if key.is_a?(Symbol) && include?(key = key.to_s)
self[key]
else
super
end
end
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
alias_method :regular_update, :update unless method_defined?(:regular_update)
#
# Assigns a new value to the hash.
#
# Example:
#
# hash = HashWithIndifferentAccess.new
# hash[:key] = "value"
#
def []=(key, value)
regular_writer(convert_key(key), convert_value(value))
end
#
# Updates the instantized hash with values from the second.
#
# Example:
#
# >> hash_1 = HashWithIndifferentAccess.new
# => {}
#
# >> hash_1[:key] = "value"
# => "value"
#
# >> hash_2 = HashWithIndifferentAccess.new
# => {}
#
# >> hash_2[:key] = "New Value!"
# => "New Value!"
#
# >> hash_1.update(hash_2)
# => {"key"=>"New Value!"}
#
def update(other_hash)
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
self
end
alias_method :merge!, :update
# Checks the hash for a key matching the argument passed in
def key?(key)
super(convert_key(key))
end
alias_method :include?, :key?
alias_method :has_key?, :key?
alias_method :member?, :key?
# Fetches the value for the specified key, same as doing hash[key]
def fetch(key, *extras)
super(convert_key(key), *extras)
end
# Returns an array of the values at the specified indicies.
def values_at(*indices)
indices.collect {|key| self[convert_key(key)]}
end
# Returns an exact copy of the hash.
def dup
HashWithIndifferentAccess.new(self)
end
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
# Does not overwrite the existing hash.
def merge(hash)
self.dup.update(hash)
end
# Removes a specified key from the hash.
def delete(key)
super(convert_key(key))
end
def stringify_keys!; self end
def symbolize_keys!; self end
def to_options!; self end
# Convert to a Hash with String keys.
def to_hash
Hash.new(default).merge(self)
end
protected
def convert_key(key)
key.kind_of?(Symbol) ? key.to_s : key
end
def convert_value(value)
case value
when Hash
value.with_indifferent_access
when Array
value.collect { |e| e.is_a?(Hash) ? e.with_indifferent_access : e }
else
value
end
end
end
class Hash #:nodoc:
def with_indifferent_access
hash = HashWithIndifferentAccess.new(self)
hash.default = self.default
hash
end
end

View File

@ -3,4 +3,4 @@ class ::Object #:nodoc:
class << self; self end
end
end

View File

@ -1,5 +1,5 @@
class NilClass #:nodoc:
def to_param
def to_query_string
nil
end
end

View File

@ -0,0 +1,27 @@
class TCPSocket
def self.wait_for_service_with_timeout(options)
start_time = Time.now
until listening_service?(options)
verbose_wait
if options[:timeout] && (Time.now > start_time + options[:timeout])
raise SocketError.new("Socket did not open within #{options[:timeout]} seconds")
end
end
end
def self.wait_for_service_termination_with_timeout(options)
start_time = Time.now
while listening_service?(options)
verbose_wait
if options[:timeout] && (Time.now > start_time + options[:timeout])
raise SocketError.new("Socket did not terminate within #{options[:timeout]} seconds")
end
end
end
end

View File

@ -0,0 +1,10 @@
module Merb #:nodoc:
module Test #:nodoc:
module RequestHelper #:nodoc:
def request(uri, env = {})
@_webrat_session ||= Webrat::MerbAdapter.new
@_webrat_session.response = @_webrat_session.request(uri, env)
end
end
end
end

View File

@ -0,0 +1,25 @@
require "action_controller"
require "action_controller/integration"
module ActionController #:nodoc:
IntegrationTest.class_eval do
include Webrat::Methods
include Webrat::Matchers
# The Rails version of within supports passing in a model and Webrat
# will apply a scope based on Rails' dom_id for that model.
#
# Example:
# within User.last do
# click_link "Delete"
# end
def within(selector_or_object, &block)
if selector_or_object.is_a?(String)
super
else
super('#' + RecordIdentifier.dom_id(selector_or_object), &block)
end
end
end
end

View File

@ -0,0 +1,11 @@
# Supports using the matchers in controller, helper, and view specs if you're
# using rspec-rails. Just add a require statement to spec/spec_helper.rb or env.rb:
#
# require 'webrat/integrations/rspec-rails'
#
require "nokogiri"
require "webrat/core/matchers"
Spec::Runner.configure do |config|
config.include(Webrat::Matchers, :type => [:controller, :helper, :view])
end

View File

@ -0,0 +1,11 @@
require "webrat/selenium"
if defined?(ActionController::IntegrationTest)
module ActionController #:nodoc:
IntegrationTest.class_eval do
include Webrat::Methods
include Webrat::Selenium::Methods
include Webrat::Selenium::Matchers
end
end
end

View File

@ -1,28 +0,0 @@
require "mechanize"
module Webrat
class MechanizeSession < Session #:nodoc:
def initialize(mechanize = WWW::Mechanize.new)
super()
@mechanize = mechanize
end
def get(url, data)
@mechanize_page = @mechanize.get(url, data)
end
def post(url, data)
@mechanize_page = @mechanize.post(url, data)
end
def response_body
@mechanize_page.content
end
def response_code
@mechanize_page.code.to_i
end
end
end

View File

@ -1,75 +1,9 @@
require "webrat/core"
require "webrat"
require "cgi"
gem "extlib"
require "extlib"
require "merb-core"
# This is a temporary hack to support backwards compatibility
# with Merb 1.0.8 until it's updated to use the new Webrat.configure
# syntax
HashWithIndifferentAccess = Mash
module Webrat
class MerbSession < Session #:nodoc:
include Merb::Test::MakeRequest
attr_accessor :response
def get(url, data, headers = nil)
do_request(url, data, headers, "GET")
end
def post(url, data, headers = nil)
do_request(url, data, headers, "POST")
end
def put(url, data, headers = nil)
do_request(url, data, headers, "PUT")
end
def delete(url, data, headers = nil)
do_request(url, data, headers, "DELETE")
end
def response_body
@response.body.to_s
end
def response_code
@response.status
end
def do_request(url, data, headers, method)
@response = request(url,
:params => (data && data.any?) ? data : nil,
:headers => headers,
:method => method)
follow_redirect
end
def follow_redirect
self.get(@response.headers['Location'], nil, @response.headers) if @response.status == 302
end
end
Webrat.configure do |config|
config.mode = :merb
end
module Merb
module Test
module RequestHelper #:nodoc:
def request(uri, env = {})
@_webrat_session ||= Webrat::MerbSession.new
@_webrat_session.response = @_webrat_session.request(uri, env)
end
def follow_redirect
@_webrat_session.follow_redirect
end
end
end
end
class Merb::Test::RspecStory #:nodoc:
def browser
@browser ||= Webrat::MerbSession.new
end
end

View File

@ -1,24 +0,0 @@
require 'webrat'
class CGIMethods #:nodoc:
def self.parse_query_parameters(params)
hash = {}
params.split('&').each do |p|
pair = p.split('=')
hash[pair[0]] = pair[1]
end
hash
end
end
module Webrat
class RackSession < Session #:nodoc:
def response_body
@response.body
end
def response_code
@response.status
end
end
end

View File

@ -1,102 +0,0 @@
require "webrat"
module Webrat
class RailsSession < Session #:nodoc:
def initialize(integration_session)
super()
@integration_session = integration_session
end
def doc_root
File.expand_path(File.join(RAILS_ROOT, 'public'))
end
def saved_page_dir
File.expand_path(File.join(RAILS_ROOT, "tmp"))
end
def get(url, data, headers = nil)
do_request(:get, url, data, headers)
end
def post(url, data, headers = nil)
do_request(:post, url, data, headers)
end
def put(url, data, headers = nil)
do_request(:put, url, data, headers)
end
def delete(url, data, headers = nil)
do_request(:delete, url, data, headers)
end
def response_body
response.body
end
def response_code
response.code.to_i
end
protected
def do_request(http_method, url, data, headers) #:nodoc:
update_protocol(url)
@integration_session.request_via_redirect(http_method, remove_protocol(url), data, headers)
end
def remove_protocol(href) #:nodoc:
if href =~ %r{^https?://www.example.com(/.*)}
$LAST_MATCH_INFO.captures.first
else
href
end
end
def update_protocol(href) #:nodoc:
if href =~ /^https:/
@integration_session.https!(true)
elsif href =~ /^http:/
@integration_session.https!(false)
end
end
def response #:nodoc:
@integration_session.response
end
end
end
module ActionController
module Integration
class Session #:nodoc:
unless instance_methods.include?("put_via_redirect")
require "webrat/rails/redirect_actions"
include Webrat::RedirectActions
end
def respond_to?(name)
super || webrat_session.respond_to?(name)
end
def method_missing(name, *args, &block)
if webrat_session.respond_to?(name)
webrat_session.send(name, *args, &block)
else
super
end
end
protected
def webrat_session
@webrat_session ||= Webrat::RailsSession.new(self)
end
end
end
end

View File

@ -1,18 +0,0 @@
# For Rails before http://dev.rubyonrails.org/ticket/10497 was committed
module Webrat
module RedirectActions #:nodoc:
def put_via_redirect(path, parameters = {}, headers = {})
put path, parameters, headers
follow_redirect! while redirect?
status
end
def delete_via_redirect(path, parameters = {}, headers = {})
delete path, parameters, headers
follow_redirect! while redirect?
status
end
end
end

View File

@ -0,0 +1,2 @@
warn("Requiring 'webrat/rspec-rails' is deprecated. Please require 'webrat/integrations/rspec-rails' instead")
require "webrat/integrations/rspec-rails"

View File

@ -1,3 +1,70 @@
require "selenium"
require "webrat"
require "selenium/client"
require "webrat/selenium/silence_stream"
require "webrat/selenium/selenium_session"
require "webrat/selenium/matchers"
require "webrat/core_extensions/tcp_socket"
module Webrat
# To use Webrat's Selenium support, you'll need the selenium-client gem installed.
# Activate it with (for example, in your <tt>env.rb</tt>):
#
# require "webrat"
#
# Webrat.configure do |config|
# config.mode = :selenium
# end
#
# == Dropping down to the selenium-client API
#
# If you ever need to do something with Selenium not provided in the Webrat API,
# you can always drop down to the selenium-client API using the <tt>selenium</tt> method.
# For example:
#
# When "I drag the photo to the left" do
# selenium.dragdrop("id=photo_123", "+350, 0")
# end
#
# == Choosing the underlying framework to test
#
# Webrat assumes you're using rails by default but it can also work with sinatra
# and merb. To take advantage of this you can use the configuration block to
# set the application_framework variable.
# require "webrat"
#
# Webrat.configure do |config|
# config.mode = :selenium
# config.application_port = 4567
# config.application_framework = :sinatra # could also be :merb
# end
#
# == Auto-starting of the appserver and java server
#
# Webrat will automatically start the Selenium Java server process and an instance
# of Mongrel when a test is run. The Mongrel will run in the "selenium" environment
# instead of "test", so ensure you've got that defined, and will run on port
# Webrat.configuration.application_port.
#
# == Waiting
#
# In order to make writing Selenium tests as easy as possible, Webrat will automatically
# wait for the correct elements to exist on the page when trying to manipulate them
# with methods like <tt>fill_in</tt>, etc. In general, this means you should be able to write
# your Webrat::Selenium tests ignoring the concurrency issues that can plague in-browser
# testing, so long as you're using the Webrat API.
module Selenium
module Methods
def response
webrat_session.response
end
def wait_for(*args, &block)
webrat_session.wait_for(*args, &block)
end
def save_and_open_screengrab
webrat_session.save_and_open_screengrab
end
end
end
end

View File

@ -0,0 +1,40 @@
module Webrat
module Selenium
class ApplicationServerFactory
def self.app_server_instance
case Webrat.configuration.application_framework
when :sinatra
require "webrat/selenium/application_servers/sinatra"
return Webrat::Selenium::ApplicationServers::Sinatra.new
when :merb
require "webrat/selenium/application_servers/merb"
return Webrat::Selenium::ApplicationServers::Merb.new
when :rails
require "webrat/selenium/application_servers/rails"
return Webrat::Selenium::ApplicationServers::Rails.new
when :external
require "webrat/selenium/application_servers/external"
return Webrat::Selenium::ApplicationServers::External.new
else
raise WebratError.new(<<-STR)
Unknown Webrat application_framework: #{Webrat.configuration.application_framework.inspect}
Please ensure you have a Webrat configuration block that specifies an application_framework
in your test_helper.rb, spec_helper.rb, or env.rb (for Cucumber).
For example:
Webrat.configure do |config|
# ...
config.application_framework = :rails
end
STR
end
end
end
end
end

View File

@ -0,0 +1,5 @@
require "webrat/selenium/application_servers/base"
require "webrat/selenium/application_servers/sinatra"
require "webrat/selenium/application_servers/merb"
require "webrat/selenium/application_servers/rails"
require "webrat/selenium/application_servers/external"

View File

@ -0,0 +1,46 @@
require "webrat/selenium/silence_stream"
module Webrat
module Selenium
module ApplicationServers
class Base
include Webrat::Selenium::SilenceStream
def boot
start
wait
stop_at_exit
end
def stop_at_exit
at_exit do
stop
end
end
def wait
$stderr.print "==> Waiting for #{Webrat.configuration.application_framework} application server on port #{Webrat.configuration.application_port}... "
wait_for_socket
$stderr.print "Ready!\n"
end
def wait_for_socket
silence_stream(STDOUT) do
TCPSocket.wait_for_service_with_timeout \
:host => "0.0.0.0",
:port => Webrat.configuration.application_port.to_i,
:timeout => 30 # seconds
end
rescue SocketError
fail
end
def prepare_pid_file(file_path, pid_file_name)
FileUtils.mkdir_p File.expand_path(file_path)
File.expand_path("#{file_path}/#{pid_file_name}")
end
end
end
end
end

View File

@ -0,0 +1,26 @@
require "webrat/selenium/application_servers/base"
module Webrat
module Selenium
module ApplicationServers
class External < Webrat::Selenium::ApplicationServers::Base
def start
warn "Webrat Ignoring Start Of Application Server Due to External Mode"
end
def stop
end
def fail
end
def pid_file
end
def wait
end
end
end
end
end

View File

@ -0,0 +1,50 @@
require "webrat/selenium/application_servers/base"
module Webrat
module Selenium
module ApplicationServers
class Merb < Webrat::Selenium::ApplicationServers::Base
def start
system start_command
end
def stop
silence_stream(STDOUT) do
pid = File.read(pid_file)
system("kill -9 #{pid}")
FileUtils.rm_f pid_file
end
end
def fail
$stderr.puts
$stderr.puts
$stderr.puts "==> Failed to boot the Merb application server... exiting!"
$stderr.puts
$stderr.puts "Verify you can start a Merb server on port #{Webrat.configuration.application_port} with the following command:"
$stderr.puts
$stderr.puts " #{start_command}"
exit
end
def pid_file
"log/merb.#{Webrat.configuration.application_port}.pid"
end
def start_command
"#{merb_command} -d -p #{Webrat.configuration.application_port} -e #{Webrat.configuration.application_environment}"
end
def merb_command
if File.exist?('bin/merb')
merb_cmd = 'bin/merb'
else
merb_cmd = 'merb'
end
end
end
end
end
end

View File

@ -0,0 +1,44 @@
require "webrat/selenium/application_servers/base"
module Webrat
module Selenium
module ApplicationServers
class Rails < Webrat::Selenium::ApplicationServers::Base
def start
system start_command
end
def stop
silence_stream(STDOUT) do
system stop_command
end
end
def fail
$stderr.puts
$stderr.puts
$stderr.puts "==> Failed to boot the Rails application server... exiting!"
$stderr.puts
$stderr.puts "Verify you can start a Rails server on port #{Webrat.configuration.application_port} with the following command:"
$stderr.puts
$stderr.puts " #{start_command}"
exit
end
def pid_file
prepare_pid_file("#{RAILS_ROOT}/tmp/pids", "mongrel_selenium.pid")
end
def start_command
"mongrel_rails start -d --chdir='#{RAILS_ROOT}' --port=#{Webrat.configuration.application_port} --environment=#{Webrat.configuration.application_environment} --pid #{pid_file} &"
end
def stop_command
"mongrel_rails stop -c #{RAILS_ROOT} --pid #{pid_file}"
end
end
end
end
end

View File

@ -0,0 +1,37 @@
require "webrat/selenium/application_servers/base"
module Webrat
module Selenium
module ApplicationServers
class Sinatra < Webrat::Selenium::ApplicationServers::Base
def start
fork do
File.open('rack.pid', 'w') { |fp| fp.write Process.pid }
exec 'rackup', File.expand_path(Dir.pwd + '/config.ru'), '-p', Webrat.configuration.application_port.to_s
end
end
def stop
silence_stream(STDOUT) do
pid = File.read(pid_file)
system("kill -9 #{pid}")
FileUtils.rm_f pid_file
end
end
def fail
$stderr.puts
$stderr.puts
$stderr.puts "==> Failed to boot the Sinatra application server... exiting!"
exit
end
def pid_file
prepare_pid_file(Dir.pwd, 'rack.pid')
end
end
end
end
end

View File

@ -1,12 +1,19 @@
if (locator == '*') {
return selenium.browserbot.locationStrategies['xpath'].call(this, "//input[@type='submit']", inDocument, inWindow)
}
var buttons = inDocument.getElementsByTagName('button');
var inputs = inDocument.getElementsByTagName('input');
return $A(inputs).find(function(candidate){
inputType = candidate.getAttribute('type');
if (inputType == 'submit' || inputType == 'image') {
var buttonText = $F(candidate);
return (PatternMatcher.matches(locator, buttonText));
}
return false;
var result = $A(inputs).concat($A(buttons)).find(function(candidate){
var type = candidate.getAttribute('type');
if (type == 'submit' || type == 'image' || type == 'button') {
var matches_id = PatternMatcher.matches(locator, candidate.id);
var matches_value = PatternMatcher.matches(locator, candidate.value);
var matches_html = PatternMatcher.matches(locator, candidate.innerHTML);
var matches_alt = PatternMatcher.matches(locator, candidate.alt);
if (matches_id || matches_value || matches_html || matches_alt) {
return true;
}
}
return false;
});
return result;

View File

@ -1,16 +1,48 @@
// Credit to: http://simonwillison.net/2006/Jan/20/escape/
RegExp.escape = function(text) {
if (!arguments.callee.sRE) {
var specials = [
'/', '.', '*', '+', '?', '|',
'(', ')', '[', ']', '{', '}', '\\'
];
arguments.callee.sRE = new RegExp(
'(\\' + specials.join('|\\') + ')', 'g'
);
}
return text.replace(arguments.callee.sRE, '\\$1');
};
var allLabels = inDocument.getElementsByTagName("label");
var regExp = new RegExp('^\\W*' + RegExp.escape(locator) + '(\\b|$)', 'i');
var candidateLabels = $A(allLabels).select(function(candidateLabel){
var regExp = new RegExp('^' + locator + '\\b', 'i');
var labelText = getText(candidateLabel).strip();
return (labelText.search(regExp) >= 0);
});
if (candidateLabels.length == 0) {
return null;
return null;
}
candidateLabels = candidateLabels.sortBy(function(s) { return s.length * -1; }); //reverse length sort
//reverse length sort
candidateLabels = candidateLabels.sortBy(function(s) {
return s.length * -1;
});
var locatedLabel = candidateLabels.first();
var labelFor = locatedLabel.getAttribute('for');
if ((labelFor == null) && (locatedLabel.hasChildNodes())) {
return locatedLabel.firstChild; //TODO: should find the first form field, not just any node
var labelFor = null;
if (locatedLabel.getAttribute('for')) {
labelFor = locatedLabel.getAttribute('for');
} else if (locatedLabel.attributes['for']) { // IE
labelFor = locatedLabel.attributes['for'].nodeValue;
}
if ((labelFor == null) && (locatedLabel.hasChildNodes())) {
return locatedLabel.getElementsByTagName('button')[0]
|| locatedLabel.getElementsByTagName('input')[0]
|| locatedLabel.getElementsByTagName('textarea')[0]
|| locatedLabel.getElementsByTagName('select')[0];
}
return selenium.browserbot.locationStrategies['id'].call(this, labelFor, inDocument, inWindow);

View File

@ -1,4 +1,5 @@
var locationStrategies = selenium.browserbot.locationStrategies;
return locationStrategies['id'].call(this, locator, inDocument, inWindow)
|| locationStrategies['name'].call(this, locator, inDocument, inWindow)
|| locationStrategies['label'].call(this, locator, inDocument, inWindow)

View File

@ -1,9 +1,32 @@
var links = inDocument.getElementsByTagName('a');
var candidateLinks = $A(links).select(function(candidateLink) {
return PatternMatcher.matches(locator, getText(candidateLink));
var textMatched = false;
var titleMatched = false;
var idMatched = false;
if (getText(candidateLink).toLowerCase().indexOf(locator.toLowerCase()) != -1) {
textMatched = true;
}
if (candidateLink.title.toLowerCase().indexOf(locator.toLowerCase()) != -1) {
titleMatched = true;
}
if (candidateLink.id.toLowerCase().indexOf(locator.toLowerCase()) != -1) {
idMatched = true;
}
return textMatched || idMatched || titleMatched;
});
if (candidateLinks.length == 0) {
return null;
}
candidateLinks = candidateLinks.sortBy(function(s) { return s.length * -1; }); //reverse length sort
//reverse length sort
candidateLinks = candidateLinks.sortBy(function(s) {
return s.length * -1;
});
return candidateLinks.first();

View File

@ -0,0 +1,4 @@
require "webrat/selenium/matchers/have_xpath"
require "webrat/selenium/matchers/have_selector"
# require "webrat/selenium/matchers/have_tag"
require "webrat/selenium/matchers/have_content"

View File

@ -0,0 +1,78 @@
module Webrat
module Selenium
module Matchers
class HasContent #:nodoc:
def initialize(content)
@content = content
end
def matches?(response)
response.session.wait_for do
response.selenium.is_text_present(text_finder)
end
rescue Webrat::TimeoutError => e
@error_message = e.message
false
end
def does_not_match?(response)
response.session.wait_for do
!response.selenium.is_text_present(text_finder)
end
rescue Webrat::TimeoutError => e
@error_message = e.message
false
end
# ==== Returns
# String:: The failure message.
def failure_message
"expected the response to #{content_message}:\n#{@error_message}"
end
# ==== Returns
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected the response to not #{content_message}"
end
def content_message
case @content
when String
"include \"#{@content}\""
when Regexp
"match #{@content.inspect}"
end
end
def text_finder
if @content.is_a?(Regexp)
"regexp:#{@content.source}"
else
@content
end
end
end
# Matches the contents of an HTML document with
# whatever string is supplied
def contain(content)
HasContent.new(content)
end
# Asserts that the body of the response contain
# the supplied string or regexp
def assert_contain(content)
hc = HasContent.new(content)
assert hc.matches?(response), hc.failure_message
end
# Asserts that the body of the response
# does not contain the supplied string or regepx
def assert_not_contain(content)
hc = HasContent.new(content)
assert !hc.matches?(response), hc.negative_failure_message
end
end
end
end

View File

@ -0,0 +1,57 @@
module Webrat
module Selenium
module Matchers
class HaveSelector
def initialize(expected)
@expected = expected
end
def matches?(response)
response.session.wait_for do
response.selenium.is_element_present("css=#{@expected}")
end
rescue Webrat::TimeoutError
false
end
def does_not_match?(response)
response.session.wait_for do
!response.selenium.is_element_present("css=#{@expected}")
end
rescue Webrat::TimeoutError
false
end
# ==== Returns
# String:: The failure message.
def failure_message
"expected following text to match selector #{@expected}:\n#{@document}"
end
# ==== Returns
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected following text to not match selector #{@expected}:\n#{@document}"
end
end
def have_selector(content)
HaveSelector.new(content)
end
# Asserts that the body of the response contains
# the supplied selector
def assert_have_selector(expected)
hs = HaveSelector.new(expected)
assert hs.matches?(response), hs.failure_message
end
# Asserts that the body of the response
# does not contain the supplied string or regepx
def assert_have_no_selector(expected)
hs = HaveSelector.new(expected)
assert !hs.matches?(response), hs.negative_failure_message
end
end
end
end

View File

@ -0,0 +1,72 @@
module Webrat
module Selenium
module Matchers
class HaveTag < HaveSelector #:nodoc:
# ==== Returns
# String:: The failure message.
def failure_message
"expected following output to contain a #{tag_inspect} tag:\n#{@document}"
end
# ==== Returns
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected following output to omit a #{tag_inspect}:\n#{@document}"
end
def tag_inspect
options = @expected.last.dup
content = options.delete(:content)
html = "<#{@expected.first}"
options.each do |k,v|
html << " #{k}='#{v}'"
end
if content
html << ">#{content}</#{@expected.first}>"
else
html << "/>"
end
html
end
def query
options = @expected.last.dup
selector = @expected.first.to_s
selector << ":contains('#{options.delete(:content)}')" if options[:content]
options.each do |key, value|
selector << "[#{key}='#{value}']"
end
Nokogiri::CSS.parse(selector).map { |ast| ast.to_xpath }
end
end
def have_tag(name, attributes = {}, &block)
HaveTag.new([name, attributes], &block)
end
alias_method :match_tag, :have_tag
# Asserts that the body of the response contains
# the supplied tag with the associated selectors
def assert_have_tag(name, attributes = {})
ht = HaveTag.new([name, attributes])
assert ht.matches?(response), ht.failure_message
end
# Asserts that the body of the response
# does not contain the supplied string or regepx
def assert_have_no_tag(name, attributes = {})
ht = HaveTag.new([name, attributes])
assert !ht.matches?(response), ht.negative_failure_message
end
end
end
end

View File

@ -0,0 +1,53 @@
module Webrat
module Selenium
module Matchers
class HaveXpath
def initialize(expected)
@expected = expected
end
def matches?(response)
response.session.wait_for do
response.selenium.is_element_present("xpath=#{@expected}")
end
rescue Webrat::TimeoutError
false
end
def does_not_match?(response)
response.session.wait_for do
!response.selenium.is_element_present("xpath=#{@expected}")
end
rescue Webrat::TimeoutError
false
end
# ==== Returns
# String:: The failure message.
def failure_message
"expected following text to match xpath #{@expected}:\n#{@document}"
end
# ==== Returns
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected following text to not match xpath #{@expected}:\n#{@document}"
end
end
def have_xpath(xpath)
HaveXpath.new(xpath)
end
def assert_have_xpath(expected)
hs = HaveXpath.new(expected)
assert hs.matches?(response), hs.failure_message
end
def assert_have_no_xpath(expected)
hs = HaveXpath.new(expected)
assert !hs.matches?(response), hs.negative_failure_message
end
end
end
end

View File

@ -0,0 +1,89 @@
module Webrat
module Selenium
class SeleniumRCServer
include Webrat::Selenium::SilenceStream
def self.boot
new.boot
end
def boot
return if selenium_grid?
start
wait
stop_at_exit
end
def start
silence_stream(STDOUT) do
remote_control.start :background => true
end
end
def stop_at_exit
at_exit do
stop
end
end
def remote_control
return @remote_control if @remote_control
server_options = { :timeout => Webrat.configuration.selenium_browser_startup_timeout }
server_options[:firefox_profile] = Webrat.configuration.selenium_firefox_profile if Webrat.configuration.selenium_firefox_profile
@remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
Webrat.configuration.selenium_server_port,
server_options)
@remote_control.jar_file = jar_path
return @remote_control
end
def jar_path
File.expand_path(__FILE__ + "../../../../../vendor/selenium-server.jar")
end
def selenium_grid?
Webrat.configuration.selenium_server_address
end
def wait
$stderr.print "==> Waiting for Selenium RC server on port #{Webrat.configuration.selenium_server_port}... "
wait_for_socket
$stderr.print "Ready!\n"
rescue SocketError
fail
end
def wait_for_socket
silence_stream(STDOUT) do
TCPSocket.wait_for_service_with_timeout \
:host => (Webrat.configuration.selenium_server_address || "0.0.0.0"),
:port => Webrat.configuration.selenium_server_port,
:timeout => 45 # seconds
end
end
def fail
$stderr.puts
$stderr.puts
$stderr.puts "==> Failed to boot the Selenium RC server... exiting!"
exit
end
def stop
silence_stream(STDOUT) do
::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
Webrat.configuration.selenium_server_port,
:timeout => 5).stop
end
end
end
end
end

View File

@ -1,137 +1,272 @@
require "webrat/core/save_and_open_page"
require "webrat/selenium/selenium_rc_server"
require "webrat/selenium/application_server_factory"
require "webrat/selenium/application_servers/base"
begin
require "selenium"
rescue LoadError => e
e.message << " (You may need to install the selenium-rc gem)"
raise e
end
module Webrat
class TimeoutError < WebratError
end
class SeleniumResponse
attr_reader :body
attr_reader :session
def initialize(session, body)
@session = session
@body = body
end
def selenium
session.selenium
end
end
class SeleniumSession
def initialize(selenium_driver) #:nodoc:
@selenium = selenium_driver
extend_selenium
define_location_strategies
include Webrat::SaveAndOpenPage
include Webrat::Selenium::SilenceStream
def initialize(*args) # :nodoc:
end
def simulate
end
def automate
yield
end
def visit(url)
@selenium.open(url)
selenium.open(url)
end
alias_method :visits, :visit
webrat_deprecate :visits, :visit
def fill_in(field_identifier, options)
locator = "webrat=#{Regexp.escape(field_identifier)}"
@selenium.type(locator, "#{options[:with]}")
locator = "webrat=#{field_identifier}"
selenium.wait_for_element locator, :timeout_in_seconds => 5
selenium.type(locator, "#{options[:with]}")
end
alias_method :fills_in, :fill_in
webrat_deprecate :fills_in, :fill_in
def response
SeleniumResponse.new(self, response_body)
end
def response_body #:nodoc:
@selenium.get_html_source
selenium.get_html_source
end
def current_url
selenium.location
end
def click_button(button_text_or_regexp = nil, options = {})
if button_text_or_regexp.is_a?(Hash) && options == {}
pattern, options = nil, button_text_or_regexp
else
elsif button_text_or_regexp
pattern = adjust_if_regexp(button_text_or_regexp)
end
pattern ||= '*'
@selenium.click("button=#{pattern}")
wait_for_result(options[:wait])
locator = "button=#{pattern}"
selenium.wait_for_element locator, :timeout_in_seconds => 5
selenium.click locator
end
alias_method :clicks_button, :click_button
webrat_deprecate :clicks_button, :click_button
def click_link(link_text_or_regexp, options = {})
pattern = adjust_if_regexp(link_text_or_regexp)
@selenium.click("webratlink=#{pattern}")
wait_for_result(options[:wait])
end
alias_method :clicks_link, :click_link
def click_link_within(selector, link_text, options = {})
@selenium.click("webratlinkwithin=#{selector}|#{link_text}")
wait_for_result(options[:wait])
end
alias_method :clicks_link_within, :click_link_within
def wait_for_result(wait_type)
if wait_type == :ajax
wait_for_ajax
elsif wait_type == :effects
wait_for_effects
if link_text_or_regexp.is_a?(Regexp)
pattern = "evalregex:#{link_text_or_regexp.inspect}"
else
wait_for_page_to_load
pattern = link_text_or_regexp.to_s
end
locator = "webratlink=#{pattern}"
selenium.wait_for_element locator, :timeout_in_seconds => 5
selenium.click locator
end
def wait_for_page_to_load(timeout = 15000)
@selenium.wait_for_page_to_load(timeout)
webrat_deprecate :clicks_link, :click_link
def click_link_within(selector, link_text, options = {})
locator = "webratlinkwithin=#{selector}|#{link_text}"
selenium.wait_for_element locator, :timeout_in_seconds => 5
selenium.click locator
end
def wait_for_ajax(timeout = 15000)
@selenium.wait_for_condition "Ajax.activeRequestCount == 0", timeout
end
webrat_deprecate :clicks_link_within, :click_link_within
def wait_for_effects(timeout = 15000)
@selenium.wait_for_condition "window.Effect.Queue.size() == 0", timeout
end
def wait_for_ajax_and_effects
wait_for_ajax
wait_for_effects
end
def selects(option_text, options = {})
def select(option_text, options = {})
id_or_name_or_label = options[:from]
if id_or_name_or_label
select_locator = "webrat=#{id_or_name_or_label}"
else
select_locator = "webratselectwithoption=#{option_text}"
end
@selenium.select(select_locator, option_text)
selenium.wait_for_element select_locator, :timeout_in_seconds => 5
selenium.select(select_locator, option_text)
end
webrat_deprecate :selects, :select
def choose(label_text)
@selenium.click("webrat=#{label_text}")
locator = "webrat=#{label_text}"
selenium.wait_for_element locator, :timeout_in_seconds => 5
selenium.click locator
end
alias_method :chooses, :choose
webrat_deprecate :chooses, :choose
def check(label_text)
@selenium.check("webrat=#{label_text}")
locator = "webrat=#{label_text}"
selenium.wait_for_element locator, :timeout_in_seconds => 5
selenium.click locator
end
alias_method :checks, :check
def is_ordered(*args) #:nodoc:
@selenium.is_ordered(*args)
alias_method :uncheck, :check
webrat_deprecate :checks, :check
def fire_event(field_identifier, event)
locator = "webrat=#{Regexp.escape(field_identifier)}"
selenium.fire_event(locator, "#{event}")
end
def dragdrop(*args) #:nodoc:
@selenium.dragdrop(*args)
def key_down(field_identifier, key_code)
locator = "webrat=#{Regexp.escape(field_identifier)}"
selenium.key_down(locator, key_code)
end
protected
def key_up(field_identifier, key_code)
locator = "webrat=#{Regexp.escape(field_identifier)}"
selenium.key_up(locator, key_code)
end
def wait_for(params={})
timeout = params[:timeout] || 5
message = params[:message] || "Timeout exceeded"
begin_time = Time.now
while (Time.now - begin_time) < timeout
value = nil
begin
value = yield
rescue Exception => e
unless is_ignorable_wait_for_exception?(e)
raise e
end
end
return value if value
sleep 0.25
end
error_message = "#{message} (after #{timeout} sec)"
if $browser && Webrat.configuration.selenium_verbose_output
error_message += <<-EOS
HTML of the page was:
#{selenium.get_html_source}"
EOS
end
raise Webrat::TimeoutError.new(error_message)
true
end
def selenium
return $browser if $browser
setup
$browser
end
webrat_deprecate :browser, :selenium
def save_and_open_screengrab
return unless File.exist?(Webrat.configuration.saved_pages_dir)
filename = "#{Webrat.configuration.saved_pages_dir}/webrat-#{Time.now.to_i}.png"
if $browser.chrome_backend?
$browser.capture_entire_page_screenshot(filename, '')
else
$browser.capture_screenshot(filename)
end
open_in_browser(filename)
end
protected
def is_ignorable_wait_for_exception?(exception) #:nodoc:
if defined?(::Spec::Expectations::ExpectationNotMetError)
return true if exception.class == ::Spec::Expectations::ExpectationNotMetError
end
return true if [::Selenium::CommandError, Webrat::WebratError].include?(exception.class)
return false
end
def setup #:nodoc:
Webrat::Selenium::SeleniumRCServer.boot
Webrat::Selenium::ApplicationServerFactory.app_server_instance.boot
create_browser
$browser.start
extend_selenium
define_location_strategies
$browser.window_maximize
end
def create_browser
$browser = ::Selenium::Client::Driver.new(Webrat.configuration.selenium_server_address || "localhost",
Webrat.configuration.selenium_server_port, Webrat.configuration.selenium_browser_key, "http://#{Webrat.configuration.application_address}:#{Webrat.configuration.application_port_for_selenium}")
$browser.set_speed(0) unless Webrat.configuration.selenium_server_address
at_exit do
silence_stream(STDOUT) do
$browser.stop
end
end
end
def adjust_if_regexp(text_or_regexp) #:nodoc:
if text_or_regexp.is_a?(Regexp)
"evalregex:#{text_or_regexp.inspect}"
else
text_or_regexp
end
"evalregex:/#{text_or_regexp}/"
end
end
def extend_selenium #:nodoc:
extensions_file = File.join(File.dirname(__FILE__), "selenium_extensions.js")
extenions_js = File.read(extensions_file)
@selenium.get_eval(extenions_js)
selenium.get_eval(extenions_js)
end
def define_location_strategies #:nodoc:
Dir[File.join(File.dirname(__FILE__), "location_strategy_javascript", "*.js")].sort.each do |file|
strategy_js = File.read(file)
strategy_name = File.basename(file, '.js')
@selenium.add_location_strategy(strategy_name, strategy_js)
selenium.add_location_strategy(strategy_name, strategy_js)
end
end
end
end
end

View File

@ -0,0 +1,18 @@
module Webrat
module Selenium
module SilenceStream
# active_support already defines silence_stream, no need to do that again if it's already present.
# http://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/kernel/reporting.rb
unless Kernel.respond_to?(:silence_stream)
def silence_stream(stream)
old_stream = stream.dup
stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
stream.sync = true
yield
ensure
stream.reopen(old_stream)
end
end
end
end
end

View File

@ -1,19 +0,0 @@
require 'webrat/rack'
require 'sinatra'
require 'sinatra/test/methods'
module Webrat
class SinatraSession < RackSession #:nodoc:
include Sinatra::Test::Methods
%w(get head post put delete).each do |verb|
define_method(verb) do |*args| # (path, data, headers = nil)
path, data, headers = *args
params = data.merge({:env => headers || {}})
self.__send__("#{verb}_it", path, params)
follow! while @response.redirect?
end
end
end
end

View File

@ -1,23 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe "Basic Auth HTTP headers" do
before do
@session = Webrat::TestSession.new
@session.basic_auth('user', 'secret')
end
it "should be present in visit" do
@session.should_receive(:get).with("/", {}, {'HTTP_AUTHORIZATION' => "Basic dXNlcjpzZWNyZXQ=\n"})
@session.visit("/")
end
it "should be present in form submits" do
@session.response_body = <<-EOS
<form method="post" action="/form1">
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/form1", {}, {'HTTP_AUTHORIZATION' => "Basic dXNlcjpzZWNyZXQ=\n"})
@session.click_button
end
end

View File

@ -1,136 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe "check" do
before do
@session = Webrat::TestSession.new
end
it "should fail if no checkbox found" do
@session.response_body = <<-EOS
<form method="post" action="/login">
</form>
EOS
lambda { @session.check "remember_me" }.should raise_error
end
it "should fail if input is not a checkbox" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<input type="text" name="remember_me" />
</form>
EOS
lambda { @session.check "remember_me" }.should raise_error
end
it "should check rails style checkboxes" do
@session.response_body = <<-EOS
<form method="get" action="/login">
<input id="user_tos" name="user[tos]" type="checkbox" value="1" />
<input name="user[tos]" type="hidden" value="0" />
<label for="user_tos">TOS</label>
<input type="submit" />
</form>
EOS
@session.should_receive(:get).with("/login", "user" => {"tos" => "1"})
@session.check "TOS"
@session.click_button
end
it "should result in the value on being posted if not specified" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<input type="checkbox" name="remember_me" />
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "remember_me" => "on")
@session.check "remember_me"
@session.click_button
end
it "should fail if the checkbox is disabled" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<input type="checkbox" name="remember_me" disabled="disabled" />
<input type="submit" />
</form>
EOS
lambda { @session.check "remember_me" }.should raise_error
end
it "should result in a custom value being posted" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<input type="checkbox" name="remember_me" value="yes" />
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "remember_me" => "yes")
@session.check "remember_me"
@session.click_button
end
end
describe "uncheck" do
before do
@session = Webrat::TestSession.new
end
it "should fail if no checkbox found" do
@session.response_body = <<-EOS
<form method="post" action="/login">
</form>
EOS
lambda { @session.uncheck "remember_me" }.should raise_error
end
it "should fail if input is not a checkbox" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<input type="text" name="remember_me" />
</form>
EOS
lambda { @session.uncheck "remember_me" }.should raise_error
end
it "should fail if the checkbox is disabled" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<input type="checkbox" name="remember_me" checked="checked" disabled="disabled" />
<input type="submit" />
</form>
EOS
lambda { @session.uncheck "remember_me" }.should raise_error
end
it "should uncheck rails style checkboxes" do
@session.response_body = <<-EOS
<form method="get" action="/login">
<input id="user_tos" name="user[tos]" type="checkbox" value="1" checked="checked" />
<input name="user[tos]" type="hidden" value="0" />
<label for="user_tos">TOS</label>
<input type="submit" />
</form>
EOS
@session.should_receive(:get).with("/login", "user" => {"tos" => "0"})
@session.check "TOS"
@session.uncheck "TOS"
@session.click_button
end
it "should result in value not being posted" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<input type="checkbox" name="remember_me" value="yes" checked="checked" />
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", {})
@session.uncheck "remember_me"
@session.click_button
end
end

View File

@ -1,288 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe "click_link" do
before do
@session = Webrat::TestSession.new
end
it "should use get by default" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.should_receive(:get).with("/page", {})
@session.click_link "Link text"
end
it "should click get links" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.should_receive(:get).with("/page", {})
@session.click_link "Link text", :method => :get
end
it "should click delete links" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.should_receive(:delete).with("/page", {})
@session.click_link "Link text", :method => :delete
end
it "should click post links" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.should_receive(:post).with("/page", {})
@session.click_link "Link text", :method => :post
end
it "should click put links" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.should_receive(:put).with("/page", {})
@session.click_link "Link text", :method => :put
end
it "should click links by regexp" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.should_receive(:get).with("/page", {})
@session.click_link /link [a-z]/i
end
it "should click rails javascript links with authenticity tokens" do
@session.response_body = <<-EOS
<a href="/posts" onclick="var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = this.href;
var s = document.createElement('input');
s.setAttribute('type', 'hidden');
s.setAttribute('name', 'authenticity_token');
s.setAttribute('value', 'aa79cb354597a60a3786e7e291ed4f74d77d3a62');
f.appendChild(s);
f.submit();
return false;">Posts</a>
EOS
@session.should_receive(:post).with("/posts", "authenticity_token" => "aa79cb354597a60a3786e7e291ed4f74d77d3a62")
@session.click_link "Posts"
end
it "should click rails javascript delete links" do
@session.response_body = <<-EOS
<a href="/posts/1" onclick="var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = this.href;
var m = document.createElement('input');
m.setAttribute('type', 'hidden');
m.setAttribute('name', '_method');
m.setAttribute('value', 'delete');
f.appendChild(m);
f.submit();
return false;">Delete</a>
EOS
@session.should_receive(:delete).with("/posts/1", {})
@session.click_link "Delete"
end
it "should click rails javascript post links" do
@session.response_body = <<-EOS
<a href="/posts" onclick="var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = this.href;
f.submit();
return false;">Posts</a>
EOS
@session.should_receive(:post).with("/posts", {})
@session.click_link "Posts"
end
it "should click rails javascript post links without javascript" do
@session.response_body = <<-EOS
<a href="/posts" onclick="var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = this.href;
f.submit();
return false;">Posts</a>
EOS
@session.should_receive(:get).with("/posts", {})
@session.click_link "Posts", :javascript => false
end
it "should click rails javascript put links" do
@session.response_body = <<-EOS
<a href="/posts" onclick="var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = this.href;
var m = document.createElement('input');
m.setAttribute('type', 'hidden');
m.setAttribute('name', '_method');
m.setAttribute('value', 'put');
f.appendChild(m);
f.submit();
return false;">Put</a></h2>
EOS
@session.should_receive(:put).with("/posts", {})
@session.click_link "Put"
end
it "should fail if the javascript link doesn't have a value for the _method input" do
@session.response_body = <<-EOS
<a href="/posts/1" onclick="var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = this.href;
var m = document.createElement('input');
m.setAttribute('type', 'hidden');
m.setAttribute('name', '_method');
f.appendChild(m);
f.submit();
return false;">Link</a>
EOS
lambda {
@session.click_link "Link"
}.should raise_error
end
it "should assert valid response" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.response_code = 501
lambda { @session.click_link "Link text" }.should raise_error
end
[200, 300, 400, 499].each do |status|
it "should consider the #{status} status code as success" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.response_code = status
lambda { @session.click_link "Link text" }.should_not raise_error
end
end
it "should fail is the link doesn't exist" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
lambda {
@session.click_link "Missing link"
}.should raise_error
end
it "should not be case sensitive" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.should_receive(:get).with("/page", {})
@session.click_link "LINK TEXT"
end
it "should match link substrings" do
@session.response_body = <<-EOS
<a href="/page">This is some cool link text, isn't it?</a>
EOS
@session.should_receive(:get).with("/page", {})
@session.click_link "Link text"
end
it "should work with elements in the link" do
@session.response_body = <<-EOS
<a href="/page"><span>Link text</span></a>
EOS
@session.should_receive(:get).with("/page", {})
@session.click_link "Link text"
end
it "should match the first matching link" do
@session.response_body = <<-EOS
<a href="/page1">Link text</a>
<a href="/page2">Link text</a>
EOS
@session.should_receive(:get).with("/page1", {})
@session.click_link "Link text"
end
it "should choose the shortest link text match" do
@session.response_body = <<-EOS
<a href="/page1">Linkerama</a>
<a href="/page2">Link</a>
EOS
@session.should_receive(:get).with("/page2", {})
@session.click_link "Link"
end
it "should treat non-breaking spaces as spaces" do
@session.response_body = <<-EOS
<a href="/page1">This&nbsp;is&nbsp;a&nbsp;link</a>
EOS
@session.should_receive(:get).with("/page1", {})
@session.click_link "This is a link"
end
it "should click link within a selector" do
@session.response_body = <<-EOS
<a href="/page1">Link</a>
<div id="container">
<a href="/page2">Link</a>
</div>
EOS
@session.should_receive(:get).with("/page2", {})
@session.click_link_within "#container", "Link"
end
it "should not make request when link is local anchor" do
@session.response_body = <<-EOS
<a href="#section-1">Jump to Section 1</a>
EOS
# Don't know why @session.should_receive(:get).never doesn't work here
@session.should_receive(:send).with('get_via_redirect', '#section-1', {}).never
@session.click_link "Jump to Section 1"
end
it "should follow relative links" do
@session.stub!(:current_url).and_return("/page")
@session.response_body = <<-EOS
<a href="sub">Jump to sub page</a>
EOS
@session.should_receive(:get).with("/page/sub", {})
@session.click_link "Jump to sub page"
end
it "should follow fully qualified local links" do
@session.response_body = <<-EOS
<a href="http://www.example.com/page/sub">Jump to sub page</a>
EOS
@session.should_receive(:get).with("http://www.example.com/page/sub", {})
@session.click_link "Jump to sub page"
end
it "should follow query parameters" do
@session.stub!(:current_url).and_return("/page")
@session.response_body = <<-EOS
<a href="?foo=bar">Jump to foo bar</a>
EOS
@session.should_receive(:get).with("/page?foo=bar", {})
@session.click_link "Jump to foo bar"
end
end

View File

@ -1,178 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe Webrat::Matchers do
include Webrat::Matchers
include Webrat::HaveTagMatcher
before(:each) do
@body = <<-EOF
<div id='main'>
<div class='inner'>hello, world!</div>
<ul>
<li>First</li>
<li>Second</li>
</ul>
</div>
EOF
end
describe "#have_xpath" do
it "should be able to match an XPATH" do
@body.should have_xpath("//div")
end
it "should not match a XPATH that does not exist" do
@body.should_not have_xpath("//p")
end
it "should be able to loop over all the matched elements" do
@body.should have_xpath("//div") { |node| node.first.name.should == "div" }
end
it "should not match of any of the matchers in the block fail" do
lambda {
@body.should have_xpath("//div") { |node| node.first.name.should == "p" }
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
end
it "should be able to use #have_xpath in the block" do
@body.should have_xpath("//div[@id='main']") { |node| node.should have_xpath("./div[@class='inner']") }
end
it "should convert absolute paths to relative in the block" do
@body.should have_xpath("//div[@id='main']") { |node| node.should have_xpath("//div[@class='inner']") }
end
it "should not match any parent tags in the block" do
lambda {
@body.should have_xpath("//div[@class='inner']") { |node| node.should have_xpath("//div[@id='main']") }
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
end
end
describe "#have_selector" do
it "should be able to match a CSS selector" do
@body.should have_selector("div")
end
it "should not match a CSS selector that does not exist" do
@body.should_not have_selector("p")
end
it "should be able to loop over all the matched elements" do
@body.should have_selector("div") { |node| node.first.name.should == "div" }
end
it "should not match of any of the matchers in the block fail" do
lambda {
@body.should have_selector("div") { |node| node.first.name.should == "p" }
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
end
it "should be able to use #have_selector in the block" do
@body.should have_selector("#main") { |node| node.should have_selector(".inner") }
end
it "should not match any parent tags in the block" do
lambda {
@body.should have_selector(".inner") { |node| node.should have_selector("#main") }
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
end
end
describe "#have_tag" do
it "should be able to match a tag" do
@body.should have_tag("div")
end
it "should not match the tag when it should not match" do
@body.should_not have_tag("p")
end
it "should be able to specify the content of the tag" do
@body.should have_tag("div", :content => "hello, world!")
end
it "should be able to specify the attributes of the tag" do
@body.should have_tag("div", :class => "inner")
end
it "should be able to loop over all the matched elements" do
@body.should have_tag("div") { |node| node.first.name.should == "div" }
end
it "should not match of any of the matchers in the block fail" do
lambda {
@body.should have_tag("div") { |node| node.first.name.should == "p" }
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
end
it "should be able to use #have_tag in the block" do
@body.should have_tag("div", :id => "main") { |node| node.should have_tag("div", :class => "inner") }
end
it "should not match any parent tags in the block" do
lambda {
@body.should have_tag("div", :class => "inner") { |node| node.should have_tag("div", :id => "main") }
}.should raise_error(Spec::Expectations::ExpectationNotMetError)
end
it "should work with items that have multiple child nodes" do
@body.should have_tag("ul") { |n|
n.should have_tag("li", :content => "First")
n.should have_tag("li", :content => "Second")
}
end
end
describe Webrat::Matchers::HasContent do
include Webrat::Matchers
before(:each) do
@body = <<-EOF
<div id='main'>
<div class='inner'>hello, world!</div>
</div>
EOF
end
describe "#matches?" do
it "should call element#contains? when the argument is a string" do
@body.should contain("hello, world!")
end
it "should call element#matches? when the argument is a regular expression" do
@body.should contain(/hello, world/)
end
end
describe "#failure_message" do
it "should include the content string" do
hc = Webrat::Matchers::HasContent.new("hello, world!")
hc.matches?(@body)
hc.failure_message.should include("\"hello, world!\"")
end
it "should include the content regular expresson" do
hc = Webrat::Matchers::HasContent.new(/hello,\sworld!/)
hc.matches?(@body)
hc.failure_message.should include("/hello,\\sworld!/")
end
it "should include the element's inner content" do
hc = Webrat::Matchers::HasContent.new(/hello,\sworld!/)
hc.matches?(@body)
hc.failure_message.should include("hello, world!")
end
end
end
end

View File

@ -1,15 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe "reloads" do
before do
@session = Webrat::TestSession.new
@session.response_body = "Hello world"
end
it "should reload the page with http referer" do
@session.should_receive(:get).with("/", {})
@session.should_receive(:get).with("/", {}, {"HTTP_REFERER"=>"/"})
@session.visit("/")
@session.reloads
end
end

View File

@ -1,53 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe "save_and_open_page" do
before do
@session = Webrat::TestSession.new
@session.response_body = <<-HTML
<html>
<head>
<link href="/stylesheets/foo.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Hello world</h1>
<img src="/images/bar.png" />
</body>
</html>
HTML
File.stub!(:exist?).and_return(true)
Time.stub!(:now).and_return(1234)
@session.stub!(:open_in_browser)
@file_handle = mock("file handle")
File.stub!(:open).with(filename, 'w').and_yield(@file_handle)
@file_handle.stub!(:write)
end
it "should rewrite css rules" do
@file_handle.should_receive(:write) do |html|
html.should =~ %r|#{@session.doc_root}/stylesheets/foo.css|s
end
@session.save_and_open_page
end
it "should rewrite image paths" do
@file_handle.should_receive(:write) do |html|
html.should =~ %r|#{@session.doc_root}/images/bar.png|s
end
@session.save_and_open_page
end
it "should open the temp file in a browser" do
@session.should_receive(:open_in_browser).with(filename)
@session.save_and_open_page
end
def filename
File.expand_path("./webrat-#{Time.now}.html")
end
end

View File

@ -1,177 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe "selects" do
before do
@session = Webrat::TestSession.new
end
it "should fail if option not found" do
@session.response_body = <<-EOS
<form method="get" action="/login">
<select name="month"><option value="1">January</option></select>
</form>
EOS
lambda { @session.selects "February", :from => "month" }.should raise_error
end
it "should fail if option not found in list specified by element name" do
@session.response_body = <<-EOS
<form method="get" action="/login">
<select name="month"><option value="1">January</option></select>
<select name="year"><option value="2008">2008</option></select>
</form>
EOS
lambda { @session.selects "February", :from => "year" }.should raise_error
end
it "should fail if specified list not found" do
@session.response_body = <<-EOS
<form method="get" action="/login">
<select name="month"><option value="1">January</option></select>
</form>
EOS
lambda { @session.selects "February", :from => "year" }.should raise_error
end
it "should fail if the select is disabled" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="month" disabled="disabled"><option value="1">January</option></select>
<input type="submit" />
</form>
EOS
lambda { @session.selects "January", :from => "month" }.should raise_error
end
it "should send value from option" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="month"><option value="1">January</option></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "month" => "1")
@session.selects "January", :from => "month"
@session.click_button
end
it "should send values with HTML encoded ampersands" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="encoded"><option value="A &amp; B">Encoded</option></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "encoded" => "A & B")
@session.selects "Encoded", :from => "encoded"
@session.click_button
end
it "should work with empty select lists" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="month"></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", 'month' => '')
@session.click_button
end
it "should work without specifying the field name or label" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="month"><option value="1">January</option></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "month" => "1")
@session.selects "January"
@session.click_button
end
it "should send value from option in list specified by name" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="start_month"><option value="s1">January</option></select>
<select name="end_month"><option value="e1">January</option></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "start_month" => "s1", "end_month" => "e1")
@session.selects "January", :from => "end_month"
@session.click_button
end
it "should send value from option in list specified by label" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<label for="start_month">Start Month</label>
<select id="start_month" name="start_month"><option value="s1">January</option></select>
<label for="end_month">End Month</label>
<select id="end_month" name="end_month"><option value="e1">January</option></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "start_month" => "s1", "end_month" => "e1")
@session.selects "January", :from => "End Month"
@session.click_button
end
it "should use option text if no value" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="month"><option>January</option></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "month" => "January")
@session.selects "January", :from => "month"
@session.click_button
end
it "should find option by regexp" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="month"><option>January</option></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "month" => "January")
@session.selects(/jan/i)
@session.click_button
end
it "should fail if no option matching the regexp exists" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="month"><option>January</option></select>
<input type="submit" />
</form>
EOS
lambda {
@session.selects(/feb/i)
}.should raise_error
end
it "should find option by regexp in list specified by label" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<label for="start_month">Start Month</label>
<select id="start_month" name="start_month"><option value="s1">January</option></select>
<label for="end_month">End Month</label>
<select id="end_month" name="end_month"><option value="e1">January</option></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "start_month" => "s1", "end_month" => "e1")
@session.selects(/jan/i, :from => "End Month")
@session.click_button
end
end

Some files were not shown because too many files have changed in this diff Show More