capybara-2.5.0/0000755000175000017500000000000012573712570012335 5ustar lunarlunarcapybara-2.5.0/History.md0000644000175000017500000007541312573712570014332 0ustar lunarlunar# Version 2.5.0 Release date: 2015-08-25 ### Fixed * Error message now raised correctly when invalid options passed to 'have_text'/'have_content' [Tom Walpole] * Rack-test driver correctly gets document title when elements on the page have nested title elements (SVG) [Tom Walpole] * 'save_page' no longer errors when using Capybara.asset_host if the page has no \ element [Travis Grathwell] * rack-test driver will ignore clicks on links with href starting with '#' or 'javascript:' ### Added * has_current_path? and associated asserts/matchers added [Tom Walpole] * Implement Node#path in selenium driver [Soutaro Matsumoto] * 'using_session' is now nestable [Tom Walpole] * 'switch_to_window' will now use waiting behavior for a matching window to appear [Tom Walpole] * Capybara.default_wait_time deprecated in favor of Capybara.default_max_wait_time to more clearly explain its purpose [Paul Pettengill] * Warning when attempting to select a disabled option * Capybara matchers are now available in RSpec view specs by default [Joshua Clayton] * 'have_link' and 'click_link' now accept Regexp for href matching [Yaniv Savir] * 'find_all' as an alias of 'all' due to collision with RSpec * Capybara.wait_on_first_by_default setting (default is false) If set to true 'first' will use Capybaras waiting behavior to wait for at least one element to appear by default * Capybara waiting behavior uses the monotonic clock if supported to ease restrictions on freezing time in tests [Dmitry Maksyoma, Tom Walpole] * Capybara.server_errors setting that allows to configure what type of errors will be raised from the server thread [Tom Walpole] * Node#send_keys to allow for sending keypresses directly to elements [Tom Walpole] * 'formmethod' attribute support in RackTest driver [Emilia Andrzejewska] * Clear field using backspaces in Selenium driver by using `:fill_options => { :clear => :backspace }` [Joe Lencioni] #Version 2.4.4 Release date: 2014-10-13 ### Fixed * Test for visit behavior updated [Phil Baker] * Removed concurrency prevention in favor of a note in the README - due to load order issues # Version 2.4.3 Relase date: 2014-09-21 ### Fixed * Update concurrency prevention to match Rails 4.2 behavior # Version 2.4.2 Release date: 2014-09-20 ### Fixed * Prevent concurrency issue when testing Rails app with default test environment [Thomas Walpole] * Tags for windows API tests fixed [Dmitry Vorotilin] * Documentation Fixes [Andrey Botalov] * Always convert visit url to string, fixes issue with visit when always_include_port was enabled [Jake Goulding] * Check correct rspec version before including ::RSpec::Matchers::Composable in Capybara RSpec matchers [Thomas Walpole, Justin Ko] # Version 2.4.1 Release date: 2014-07-03 ### Added * 'assert_text', 'assert_no_text', 'assert_title', 'assert_no_title' methods added [Andrey Botalov] * have_title matcher now supports :wait option [Andrey Botalov] * More descriptive have_text error messages [Andrey Botalov] * New modal API ('accept_alert', 'accept_confirm', 'dismiss_confirm', 'accept_prompt', 'dismiss_prompt') - [Mike Pack, Thomas Walpole] * Warning when attempting to set contents of a readonly element * Suport for and/or compounding of Capybara's RSpec matchers for RSpec 3 [Thomas Walpole] * :fill_options option for 'fill_in' method that propagates to 'set' to allow for driver specific modification of how fields are filled in [Gabriel Sobrinho, Thomas Walpole] * Improved selector/filter description in failure messages [Thomas Walpole] ### Fixed * HaveText error message now shows the text checked all the time * RackTest driver no longer attempts to follow an anchor tag without an href attribute * Warnings under RSpec 3 * Handle URI schemes like about: correctly [Andrey Botalov] * RSpecs expose_dsl_globally option is now followed [Myron Marston, Thomas Walpole] # Version 2.3.0 Release date: 2014-06-02 ### Added * New window management API [Andrey Botalov] * Speed improvement for visible text detection in RackTest [Thomas Walpole] Thanks to Phillipe Creux for instigating this * RSpec 3 compatability * 'save_and_open_screenshot' functionality [Greg Lazarev] * Server errors raised on visit and synchronize [Jonas Nicklas] ### Fixed * CSSHandlers now derives from BasicObject so globally included functions (concat, etc) shouldn't cause issues [Thomas Walpole] * touched reset after session is reset [lesliepc16] # Version 2.2.1 Release date: 2014-01-06 ### Fixed * Reverted a change in 2.2.0 which navigates to an empty file on `reset`. Capybara, now visits `about:blank` like it did before. [Jonas Nicklas] # Version 2.2.0 Release date: 2013-11-21 ### Added * Add `go_back` and `go_forward` methods. [Vasiliy Ermolovich] * Support RSpec 3 [Thomas Holmes] * `has_button?`, `has_checked_field?` and `has_unchecked_field?` accept options, like other matchers. [Carol Nichols] * The `assert_selector` and `has_text?` methods now support the `:wait` option [Vasiliy Ermolovich] * RackTest's visible? method now checks for the HTML5 `hidden` attribute. * Results from `#all` now delegate the `sample` method. [Phil Lee] * The `set` method now works for contenteditable attributes under Selenium. [Jon Rowe] * radio buttons and check boxes can be filtered by option value, useful when selecting by name [Jonas Nicklas] * feature blocks can be nested within other feature blocks in RSpec tests [Travis Gaff] ### Fixed * Fixed race conditions causing stale element errors when filtering by text. [Jonas Nicklas] * Resetting the page is now synchronous and navigates to an empty HTML file, instead of `about:blank`, fixing hanging issues in JRuby. [Jonas Nicklas] * Fixed cookies not being set when path is blank under RackTest [Thomas Walpole] * Clearing fields now correctly causes change events [Jonas Nicklas] * Navigating to an absolute URI without trailing slash now works as expected under RackTest [Jonas Nicklas] * Checkboxes without assigned value default to `on` under RackTest [Nigel Sheridan-Smith] * Clicks on buttons with no form associated with them are ignored in RackTest instead of raising an obscure exception. [Thomas Walpole] * execute_script is now a session method [Andrey Botalov] * Nesting `within_window` and `within_frame` inside `within` resets the scope so that they behave like a user would expect [Thomas Walpole] * Improve handling of newlines in textareas [Thomas Walpole] * `Capybara::Result` delegates its inspect method, so as not to confuse users [Sam Rawlins] * save_page always returns a full path, fixes problems with Launchy [Jonas Nicklas] * Selenium driver's `quit` method does nothing when browser hasn't been loaded [randoum] * Capybara's WEBRick server now propertly respects the server_host option [Dmitry Vorotilin] * gemspec now includes license information [Jonas Nicklas] # Version 2.1.0 Release date: 2013-04-09 ### Changed * Hard version requirement on Ruby >= 1.9.3. Capybara will no longer install on 1.8.7. [Felix Schäfer] * Capybara no longer depends on the `selenium-webdriver` gem. Add it to your Gemfile if you wish to use the Selenium driver. [Jonas Nicklas] * `Capybara.ignore_hidden_elements` defaults to `true`. [Jonas Nicklas] * In case of multiple matches `smart` matching is used by default. Set `Capybara.match = :one` to revert to old behaviour. [Jonas Nicklas]. * Options in select boxes use smart matching and no longer need to match exactly. Set `Capybara.exact_options = false` to revert to old behaviour. [Jonas Nicklas]. * Visibility of text depends on `Capybara.ignore_hidden_elements` instead of always returning only visible text. Set `Capybara.visible_text_only = true` to revert to old behaviour. [Jonas Nicklas] * Cucumber cleans up session after scenario instead. This is consistent with RSpec and makes more sense, since we raise server errors in `reset!`. [Jonas Nicklas] ### Added * All actions (`click_link`, `fill_in`, etc...) and finders now take an options hash, which is passed through to `find`. [Jonas Nicklas] * CSS selectors are sent straight through to driver instead of being converted to XPath first. Enables the use of some pseudo selectors, such as `invalid` in some drivers. [Thomas Walpole] * `Capybara.asset_host` option, which inserts a `base` tag into the page on `save_and_open_page`, eases debugging with the Rails asset pipeline. [Steve Hull] * `exact` option, can specify whether to match substrings or entire text. [Jonas Nicklas] * `match` option, can specify behaviour in case of multiple matches. [Jonas Nicklas] * `wait` option, can specify how long to wait for a given action/finder. [Jonas Nicklas] * Config option which disables bubbling of errors raised inside server. [Jonas Nicklas] * `text` now takes a parameter which makes it possible to return either all text or only visible text. The default depends on `Capybara.ignore_hidden_elements`. `Capybara.visible_text_only` option is available for compatibility. [Jonas Nicklas] * `has_content?` and `has_text?` now take the same count options as `has_selector?` [Andrey Botalov] * `current_scope` is now public API, returns the current element when `within` is used. [Martijn Walraven] * `find("input").disabled?` returns true if a node is disabled. [Ben Lovell] * Find disabled fields and buttons with `:disabled => false`. [Jonas Nicklas] * `find("input").hover` moves the mouse to the element in supported drivers. [Thomas Walpole] * RackTest driver now support `form` attribute on form elements. [Thomas Walpole] * `page.title` returns the page title. [Terry Progetto] * `has_title?` matcher to assert on page title. [Jonas Nicklas] * The gem is now signed with a certicficate. The public key is available in the repo. [Jonas Nicklas] * `:select` and `:textarea` are valid options for the `:type` filter on `find_field` and `has_field?`. [Yann Plancqueel] ### Fixed * Fixed race conditions when synchronizing across multiple nodes [Jonas Nicklas] * Fixed race conditions in deeply nested selectors [Jonas Nicklas] * Fix issue with `within_frame`, where selecting multiple nested frames didn't work as intended. [Thomas Walpole] * RackTest no longer fills in readonly textareas. [Thomas Walpole] * Don't use autoload to load files, require them directly instead. [Jonas Nicklas] * Rescue weird exceptions when booting server [John Wilger] * Non strings are now properly cast when using the maxlength attribute [Jonas Nicklas] # Version 2.0.3 Release date: 2013-03-26 * Check against Rails version fixed to work with Rails' master branch now returning a Gem::Version [Jonas Nicklas] * Use posix character class for whitespace replace, solves various encoding problems on Ruby 2.0.0 and JRuby. [Ben Cates] # Version 2.0.2 Release date: 2012-12-31 ### Changed * Capybara no longer uses thin as a server if it is available, due to thread safety issues. Now Capybara always defaults to WEBrick. [Jonas Nicklas] ### Fixed * Suppress several warnings [Kouhei Sutou] * Fix default host becoming nil [Brian Cardarella] * Fix regression in 2.0.1 which caused node comparisons with non node objects to throw an exception [Kouhei Sotou] * A few changes to the specs, only relevant to driver authors [Jonas Nicklas] * Encoding error under JRuby [Piotr Krawiec] * Ruby 2 encoding fix [Murahashi Sanemat Kenichi] * Catch correct exception on server timeout [Jonathan del Strother] # Version 2.0.1 Release date: 2012-12-21 ### Changed * Move the RackTest driver override with the `:respect_data_method` option enabled from capybara/rspec to capybara/rails, so that it is enabled in Rails projects that don't use RSpec. [Carlos Antonio da Silva] * `source` is now an alias for `html`. RackTest no longer returns modifications to `html`. This basically codifies the behaviour which we've had for a while anyway, and should have minimal impact for end users. For driver authors, it means that they only have to implement `html`, and not `source`. [Jonas Nicklas] ### Fixed * Visiting relative URLs when `app_host` is set and no server is running works as expected. [Jonas Nicklas] * `fill_in` works properly under Selenium again when the caret is not at the end of the field before the method is called. [Douwe Maan, Jonas Nicklas, Jari Bakken] * `attach_file` can once again be given a Pathname [Jake Goulding] # Version 2.0.0 Release date: 2012-11-05 ### Changed * Dropped official support for Ruby 1.8.x. [Jonas Nicklas] * `respect_data_method` default to `false` for the RackTest driver in non-rails applications. That means that Capybara no longer picks up `data-method="post"` et. al. from links by default when you haven't required capybara/rails [Jonas Nicklas] * `find` now raises an error if more than one element was found. Since `find` is used by most actions, like `click_link` under the surface, this means that all actions need to unambiguous in the future. [Jonas Nicklas] * All methods which find or manipulate fields or buttons now ignore them when they are disabled. [Jonas Nicklas] * Can no longer find elements by id via `find(:foo)`, use `find("#foo")` or `find_by_id("foo")` instead. [Jonas Nicklas] * `Element#text` on RackTest now only returns visible text and normalizes (strips) whitespace, as with Selenium [Mark Dodwell, Jo Liss] * `has_content?` now checks the text value returned by `Element#text`, as opposed to querying the DOM. Which means it does not match hidden text. [Ryan Montgomery, Mark Dodwell, Jo Liss] * #394: `#body` now returns the unmodified source (like `#source`), not the current state of the DOM (like `#html`), by popular request [Jonas Nicklas] * `Node#all` no longer returns an array, but rather an enumerable `Capybara::Result` [Jonas Nicklas] * The arguments to `select` and `unselect` needs to be the exact text of an option in a select box, substrings are no longer allowed [Jonas Nicklas] * The `options` option to `has_select?` must match the exact set of options. Use `with_options` for the old behaviour. [Gonzalo Rodriguez] * The `selected` option to `has_select?` must match all selected options for multiple selects. [Gonzalo Rodriguez] * Various internals for running driver specs, this should only affect driver authors [Jonas Nicklas] * Rename `Driver#body` to `Driver#html` (relevant only for driver authors) [Jo Liss] ### Removed * No longer possible to specify `failure_message` for custom selectors. [Jonas Nicklas] * #589: `Capybara.server_boot_timeout` has been removed in favor of a higher (60-second) hard-coded timeout [Jo Liss] * `Capybara.prefer_visible_elements` has been removed, as it is no longer needed with the changed find semantics [Jonas Nicklas] * `Node#wait_until` and `Session#wait_until` have been removed. See `Node#synchronize` for an alternative [Jonas Nicklas] * `Capybara.timeout` has been removed [Jonas Nicklas] * The `:resynchronize` option has been removed from the Selenium driver [Jonas Nicklas] * The `rows` option to `has_table?` has been removed without replacement. [Jonas Nicklas] ### Added * Much improved error message [Jonas Nicklas] * Errors from inside the session for apps running in a server are raised when session is reset [James Tucker, Jonas Nicklas] * A ton of new selectors built in out of the box, like `field`, `link`, `button`, etc... [Adam McCrea, Jonas Nicklas] * `has_text?` has been added as an alias for `has_content?` [Jonas Nicklas] * Add `Capybara.server_host` option (default: 127.0.0.1) [David Balatero] * Add `:type` option for `page.has_field?` [Gonzalo Rodríguez] * Custom matchers can now be specified in CSS in addition to XPath [Jonas Nicklas] * `Node#synchronize` method to rerun a block of code if certain errors are raised [Jonas Nicklas] * `Capybara.always_include_port` config option always includes the server port in URLs when using `visit`. Facilitates testing different domain names. [Douwe Maan] * Redirect limit for RackTest driver is configurable [Josh Lane] * Server port can be manually specified during initialization of server. [Jonas Nicklas, John Wilger] * `has_content?` and `has_text?` can be given a regular expression [Vasiliy Ermolovich] * Multiple files can be uploaded with `attach_file` [Jarl Friis] ### Fixed * Nodes found via `all` are no longer reloaded. This fixes weird quirks where nodes would seemingly randomly replace themselves with other nodes [Jonas Nicklas] * Session is only reset if it has been modified, dramatically improves performance if only part of the test suite runs Capybara. [Jonas Nicklas] * Test suite now passes on Ruby 1.8 [Jo Liss] * #565: `require 'capybara/dsl'` is no longer necessary [Jo Liss] * `Rack::Test` now respects ports when changing hosts [Jo Liss] * #603: `Rack::Test` now preserves the original referer URL when following a redirect [Rob van Dijk] * Rack::Test now does not send a referer when calling `visit` multiple times [Jo Liss] * Exceptions during server boot now propagate to main thread [James Tucker] * RSpec integration now cleans up before the test instead of after [Darwin] * If `respect_data_method` is true, the data-method attribute can be capitalized [Marco Antonio] * Rack app boot timing out raises an error as opposed to just logging to STDOUT [Adrian Irving-Beer] * `#source` returns an empty string instead of nil if no pages have been visited [Jonas Nicklas] * Ignore first leading newline in textareas in RackTest [Vitalii Khustochka] * `within_frame` returns the value of the given block [Alistair Hutchison] * Running `Node.set` on text fields will not trigger more than one change event [Andrew Kasper] * Throw an error when an option is given to a finder method, like `all` or `has_selector?` which Capybara doesn't understand [Jonas Nicklas] * Two references to the node now register as equal when comparing them with `==` [Jonas Nicklas] * `has_text` (`has_content`) now accepts non-string arguments, like numbers. [Jo Liss] * `has_text` and `text` now correctly normalize Unicode whitespace, such as ` `. [Jo Liss] * RackTest allows protocol relative URLs [Jonas Nicklas] * Arguments are cast to string where necessary, so that e.g. `click_link(:foo)` works as expected. [Jonas Nicklas] * `:count => 0` now works as expected [Jarl Friis] * Fixed race conditions on negative assertions when removing nodes [Jonas Nicklas] # Version 1.1.4 Release date: 2012-11-28 ### Fixed * Fix more race conditions on negative assertions. [Jonas Nicklas] # Version 1.1.3 Release date: 2012-10-30 ### Fixed: * RackTest driver ignores leading newline in textareas, this is consistent with the spec and how browsers behave. [Vitalii Khustochka] * Nodes found via `all` and `first` are never reloaded. This fixes issues where a node would sometimes magically turn into a completely different node. [Jonas Nicklas] * Fix race conditions on negative assertions. This fixes issues where removing an element and asserting on its non existence could cause StaleElementReferenceError and similar to be thrown. [Jonas Nicklas] * Options are no longer lost when reloading elements. This fixes issues where reloading an element would cause a non-matching element to be found, because options to `find` were ignored. [Jonas Nicklas] # Version 1.1.2 Release date: 2011-11-15 ### Fixed * #541: Make attach_file work with selenium-webdriver >=2.12 [Jonas Nicklas] # Version 1.1.0 Release date: 2011-09-02 ### Fixed * Sensible inspect for Capybara::Session [Jo Liss] * Fix headers and host on redirect [Matt Colyer, Jonas Nicklas, Kim Burgestrand] * using_driver now restores the old driver instead of reverting to the default [Carol Nichols] * Errors when following links relative to the root path under rack-test [Jonas Nicklas, Kim Burgestrand] * Make sure exit codes are propagated properly [Edgar Beigarts] ### Changed * resynchronization is off by default under Selenium ### Added * Elements are automatically reloaded (including parents) during wait [Jonas Nicklas] * Rescue driver specific element errors, such as the dreaded ObsoleteElementError and retry [Jonas Nicklas] * Raise an error if something has frozen time [Jonas Nicklas] * Allow within to take a node instead of a selector [Peter Williams] * Using wait_time_time to change wait time for a block of code [Jonas Nicklas, Kim Burgestrand] * Option for rack-test driver to disable data-method hack [Jonas Nicklas, Kim Burgestrand] # Version 1.0.1 Release date: 2011-08-12 ### Fixed * Dependend on selenium-webdriver ~>2.0 and fix deprecations [Thomas Walpole, Jo Liss] * Depend on Launch 2.0 [Jeremy Hinegardner] * Rack-Test ignores fill in on fields with maxlength="" # Version 1.0.0 Release date: 2011-06-14 ### Added * Added DSL for acceptance tests, inspired by Luismi Cavallé's Steak [Luismi Cavalle and Jonas Nicklas] * Selenium driver automatically waits for AJAX requests to finish [mgiambalvo, Nicklas Ramhöj and Jonas Nicklas] * Support for switching between multiple named sessions [Tristan Dunn] * failure_message can be specified for Selectors [Jonas Nicklas] * RSpec matchers [David Chelimsky and Jonas Nicklas] * Added save_page to save tempfile without opening in browser [Jeff Kreeftmeijer] * Cucumber now switches automatically to a registered driver if the tag matches the name [Jonas Nicklas] * Added Session#text [Jonas Nicklas and Scott Cytacki] * Added Session#html as an alias for Session#body [Jo Liss] * Added Session#current_host method [Jonas Nicklas] * Buttons can now be clicked by title [Javier Martin] * :headers option for RackTest driver to set custom HTTP headers [Jonas Nicklas] ### Removed * Culerity and Celerity drivers have been removed and split into separate gems [Gabriel Sobrinho] ### Deprecated * `include Capybara` has been deprecated in favour of `include Capybara::DSL` [Jonas Nicklas] ### Changed * Rack test driver class has been renamed from Capybara::Driver::RackTest to Capybara::RackTest::Driver [Jonas Nicklas] * Selenium driver class has been renamed from Capybara::Driver::Selenium to Capybara::Selenium::Driver [Jonas Nicklas] * Capybara now prefers visible elements over hidden elements, disable by setting Capybara.prefer_visible_elements = false [Jonas Nicklas and Nicklas Ramhöj] * For RSpec, :type => :request is now supported (and preferred over :acceptance) [Jo Liss] * Selenium driver tried to wait for AJAX requests to finish before proceeding [Jonas Nicklas and Nicklas Ramhöj] * Session no longer uses method missing, uses explicit delegates instead [Jonas Nicklas] ### Fixed * The Rack::Test driver now respects maxlength on text fields [Guilherme Carvalho] * Allow for more than one save_and_open_page call per second [Jo Liss] * Automatically convert options to :count, :minimum, :maximum, etc. to integers [Keith Marcum] * Rack::Test driver honours maxlength on input fields [Guilherme Carvalho] * Rack::Test now works as expected with domains and subdomains [Jonas Nicklas] * Session is reset more thoroughly between tests. [Jonas Nicklas] * Raise error when uploading non-existant file [Jonas Nicklas] * Rack reponse body should respond to #each [Piotr Sarnacki] * Deprecation warnings with selenium webdriver 0.2.0 [Aaron Gibraltar] * Selenium Chrome no longer YELLS tagname [Carl Jackson & David W. Frank] * Capybara no longer strips encoding before sending to Rack [Jonas Nicklas] * Improve handling of relative URLs [John Barton] * Readd and fix build_rack_mock_session [Jonas Nicklas, Jon Leighton] # Version 0.4.1 Release date: 2011-01-21 ### Added * New click_on alias for click_link_or_button, shorter yet unambiguous. [Jonas Nicklas] * Finders now accept :visible => false which will find all elements regardless of Capybara.ignore_hidden_elements [Jonas Nicklas] * Configure how the server is started via Capybara.server { |app, port| ... }. [John Firebough] * Added :between, :maximum and :minimum options to has_selector and friends [James B. Byrne] * New Capybara.string util function which allows matchers on arbitrary strings, mostly for helper and view specs [David Chelimsky and Jonas Nicklas] * Server boot timeout is now configurable, via Capybara.server_boot_timeout [Adam Cigánek] * Built in support for RSpec [Jonas Nicklas] * Capybara.using_driver to switch to a different driver temporarily [Jeff Kreeftmeijer] * Added Session#first which is somewhat speedier than Session#all, use it internally for speed boost [John Firebaugh] ### Changed * Session#within now accepts the same arguments as other finders, like Session#all and Session#find [Jonas Nicklas] ### Removed * All deprecations from 0.4.0 have been removed. [Jonas Nicklas] ### Fixed * Don't mangle URLs in save_and_open_page when using self-closing tags [Adam Spiers] * Catch correct error when server boot times out [Jonas Nicklas] * Celerity driver now properly passes through options, making it configurable [Jonas Nicklas] * Better implementation of attributes in C[ue]lerity, should fix issues with attributes with strange names [Jonas Nicklas] * Session#find no longer swallows errors [Jonas Nicklas] * Fix problems with multiple file inputs [Philip Arndt] * Submit multipart forms as multipart under rack-test even if they contain no files [Ryan Kinderman] * Matchers like has_select? and has_checked_field? now work with dynamically changed values [John Firebaugh] * Preserve order of rack params [Joel Chippindale] * RackTest#reset! is more thorough [Joel Chippindale] # Version 0.4.0 Release date: 2010-10-22 ### Changed * The Selector API was changed slightly, use Capybara.add_selector, see README ### Fixed * Celerity driver is registered properly * has_selector? and has_no_selector? added to DSL * Multiple selects return correct values under C[cu]lerity * Naked query strings are handled correctly by rack-test # Version 0.4.0.rc Release date: 2010-10-12 ### Changed * within and find/locate now follow the XPath spec in that //foo finds all nodes in the document, instead of only for the context node. See this post for details: http://groups.google.com/group/ruby-capybara/browse_thread/thread/b129067979df21b3 * within now executes within the first found instance of the selector, not in all of them * find now waits for AJAX requests and raises an exception when the element is not found (same as locate used to do) * The default selector is now CSS, not XPath ### Deprecated * Session#click has been renamed click_link_or_button and the old click has been deprecated * Node#node has been renamed native * Node#locate is deprecated in favor of Node#find, which now behaves identically * Session#drag is deprecated, please use Node#drag_to(other_node) instead ### Added * Pretty much everything is properly documented now * It's now possible to call all session methods on nodes, like `find('#foo').fill_in(...)` * Custom selectors can be added with Capybara::Selector.add * The :id selector is added by default, use it lile `find(:id, 'foo')` or `find(:foo)` * Added Node#has_selector? so any kind of selector can be queried. * Added Capybara.configure for less wordy configuration * Added within_window to switch between different windows (currently Selenium only) * Capybara.server_port to provide a fixed port if wanted (defaults to automatic selection) ### Fixed * CSS selectors with multiple selectors, such as "h1, h2" now work correctly * Port is automatically assigned instead of guessing * Strip encodings in rack-test, no more warnings! * RackTest no longer submits disabled fields * Servers no longer output annoying debug information when started * TCP port selection is left to Ruby to decide, no more port guessing * Select boxes now return option value instead of text if present * The default has been changed from localhost to 127.0.0.1, should fix some obscure selenium bugs * RackTest now supports complex field names, such as foo[bar][][baz] # Version 0.3.9 Release date: 2010-07-03 ### Added * status_code which returns the HTTP status code of the last response (no Selenium!) * Capybara.save_and_open_page to store tempfiles * RackTest and Culerity drivers now clean up after themselves properly ### Fixed * When no rack app is set and the app is called, a more descriptive error is raised * select now works with optgroups * Don't submit image buttons unless they were clicked under rack-test * Support custom field types under Selenium * Support input fields without a type, treat them as though they were text fields * Redirect now throws an error after 5 redirects, as per RFC * Selenium now properly raises an error when Node#trigger is called * Node#value now returns the correct value for textareas under rack-test # Version 0.3.8 Release date: 2010-05-12 ### Added * Within_frame method to execute a block of code within a particular iframe (Selenium only!) ### Fixed * Single quotes are properly escaped with `select` under rack-test and Selenium. * The :text option for searches now escapes regexp special characters when a string is given. * Selenium now correctly checks already checked checkboxes (same with uncheck) * Timing issue which caused Selenium to hang under certain circumstances. * Selenium now resolves attributes even if they are given as a Symbol # Version 0.3.7 Release date: 2010-04-09 This is a drop in compatible maintainance release. It's mostly important for driver authors. ### Added * RackTest scans for data-method which rails3 uses to change the request method ### Fixed * Don't hang when starting server on Windoze ### Changed * The driver and session specs are now located inside lib! Driver authors can simply require them. # Version 0.3.6 Release date: 2010-03-22 This is a maintainance release with minor bug fixes, should be drop in compatible. ### Added * It's now possible to load in external drivers ### Fixed * has_content? ignores whitespace * Trigger events when choosing radios and checking checkboxes under Selenium * Make Capybara.app totally optional when running without server * Changed fallback host so it matches the one set up by Rails' integration tests # Version 0.3.5 Release date: 2010-02-26 This is a mostly backwards compatible release, it does break the API in some minor places, which should hopefully not affect too many users, please read the release notes carefully! ### Breaking * Relative searching in a node (e.g. find('//p').all('//a')) will now follow XPath standard this means that if you want to find descendant nodes only, you'll need to prefix a dot! * `visit` now accepts fully qualified URLs for drivers that support it. * Capybara will always try to run a rack server, unless you set Capybara.run_sever = false ### Changed * thin is preferred over mongrel and webrick, since it is Ruby 1.9 compatible * click_button and click will find , clicking them does nothing in RackTest ### Added * Much improved error messages in a multitude of places * More semantic page querying with has_link?, has_button?, etc... * Option to ignore hidden elements when querying and interacting with the page * Support for multiple selects ### Fixed * find_by_id is no longer broken * clicking links where the image's alt attribute contains the text is now possible * within_fieldset and within_table work when the default selector is CSS * boolean attributes work the same across drivers (return true/false) capybara-2.5.0/README.md0000644000175000017500000007424412573712570013627 0ustar lunarlunar# Capybara [![Build Status](https://secure.travis-ci.org/jnicklas/capybara.png)](http://travis-ci.org/jnicklas/capybara) [![Dependency Status](https://gemnasium.com/jnicklas/capybara.png)](https://gemnasium.com/jnicklas/capybara) [![Code Climate](https://codeclimate.com/github/jnicklas/capybara.png)](https://codeclimate.com/github/jnicklas/capybara) Capybara helps you test web applications by simulating how a real user would interact with your app. It is agnostic about the driver running your tests and comes with Rack::Test and Selenium support built in. WebKit is supported through an external gem. **Need help?** Ask on the mailing list (please do not open an issue on GitHub): http://groups.google.com/group/ruby-capybara ## Table of contents - [Key benefits](#key-benefits) - [Setup](#setup) - [Using Capybara with Cucumber](#using-capybara-with-cucumber) - [Using Capybara with RSpec](#using-capybara-with-rspec) - [Using Capybara with Test::Unit](#using-capybara-with-testunit) - [Using Capybara with MiniTest::Spec](#using-capybara-with-minitestspec) - [Drivers](#drivers) - [Selecting the Driver](#selecting-the-driver) - [RackTest](#racktest) - [Selenium](#selenium) - [Capybara-webkit](#capybara-webkit) - [Poltergeist](#poltergeist) - [The DSL](#the-dsl) - [Navigating](#navigating) - [Clicking links and buttons](#clicking-links-and-buttons) - [Interacting with forms](#interacting-with-forms) - [Querying](#querying) - [Finding](#finding) - [Scoping](#scoping) - [Working with windows](#working-with-windows) - [Scripting](#scripting) - [Modals](#modals) - [Debugging](#debugging) - [Matching](#matching) - [Exactness](#exactness) - [Strategy](#strategy) - [Transactions and database setup](#transactions-and-database-setup) - [Asynchronous JavaScript (Ajax and friends)](#asynchronous-javascript-ajax-and-friends) - [Using the DSL elsewhere](#using-the-dsl-elsewhere) - [Calling remote servers](#calling-remote-servers) - [Using the sessions manually](#using-the-sessions-manually) - [XPath, CSS and selectors](#xpath-css-and-selectors) - [Beware the XPath // trap](#beware-the-xpath--trap) - [Configuring and adding drivers](#configuring-and-adding-drivers) - [Gotchas:](#gotchas) - [Development](#development) ## Key benefits - **No setup** necessary for Rails and Rack application. Works out of the box. - **Intuitive API** which mimics the language an actual user would use. - **Switch the backend** your tests run against from fast headless mode to an actual browser with no changes to your tests. - **Powerful synchronization** features mean you never have to manually wait for asynchronous processes to complete. ## Setup Capybara requires Ruby 1.9.3 or later. To install, add this line to your `Gemfile` and run `bundle install`: ```ruby gem 'capybara' ``` If the application that you are testing is a Rails app, add this line to your test helper file: ```ruby require 'capybara/rails' ``` **Note:** In Rails 4.0/4.1 the default test environment (`config/environments/test.rb`) is [not threadsafe](https://github.com/rails/rails/issues/15089). If you experience random errors about missing constants, add `config.allow_concurrency = false` to `config/environments/test.rb`. If the application that you are testing is a Rack app, but not Rails, set Capybara.app to your Rack app: ```ruby Capybara.app = MyRackApp ``` If you need to test JavaScript, or if your app interacts with (or is located at) a remote URL, you'll need to [use a different driver](#drivers). ## Using Capybara with Cucumber The `cucumber-rails` gem comes with Capybara support built-in. If you are not using Rails, manually load the `capybara/cucumber` module: ```ruby require 'capybara/cucumber' Capybara.app = MyRackApp ``` You can use the Capybara DSL in your steps, like so: ```ruby When /I sign in/ do within("#session") do fill_in 'Email', :with => 'user@example.com' fill_in 'Password', :with => 'password' end click_button 'Sign in' end ``` You can switch to the `Capybara.javascript_driver` (`:selenium` by default) by tagging scenarios (or features) with `@javascript`: ```ruby @javascript Scenario: do something Ajaxy When I click the Ajax link ... ``` There are also explicit `@selenium` and `@rack_test` tags set up for you. ## Using Capybara with RSpec Load RSpec 2.x support by adding the following line (typically to your `spec_helper.rb` file): ```ruby require 'capybara/rspec' ``` If you are using Rails, put your Capybara specs in `spec/features`. If you are not using Rails, tag all the example groups in which you want to use Capybara with `:type => :feature`. You can now write your specs like so: ```ruby describe "the signin process", :type => :feature do before :each do User.make(:email => 'user@example.com', :password => 'password') end it "signs me in" do visit '/sessions/new' within("#session") do fill_in 'Email', :with => 'user@example.com' fill_in 'Password', :with => 'password' end click_button 'Sign in' expect(page).to have_content 'Success' end end ``` Use `:js => true` to switch to the `Capybara.javascript_driver` (`:selenium` by default), or provide a `:driver` option to switch to one specific driver. For example: ```ruby describe 'some stuff which requires js', :js => true do it 'will use the default js driver' it 'will switch to one specific driver', :driver => :webkit end ``` Capybara also comes with a built in DSL for creating descriptive acceptance tests: ```ruby feature "Signing in" do background do User.make(:email => 'user@example.com', :password => 'caplin') end scenario "Signing in with correct credentials" do visit '/sessions/new' within("#session") do fill_in 'Email', :with => 'user@example.com' fill_in 'Password', :with => 'caplin' end click_button 'Sign in' expect(page).to have_content 'Success' end given(:other_user) { User.make(:email => 'other@example.com', :password => 'rous') } scenario "Signing in as another user" do visit '/sessions/new' within("#session") do fill_in 'Email', :with => other_user.email fill_in 'Password', :with => other_user.password end click_button 'Sign in' expect(page).to have_content 'Invalid email or password' end end ``` `feature` is in fact just an alias for `describe ..., :type => :feature`, `background` is an alias for `before`, `scenario` for `it`, and `given`/`given!` aliases for `let`/`let!`, respectively. Finally, Capybara matchers are supported in view specs: ```ruby RSpec.describe "todos/show.html.erb", type: :view do it "displays the todo title" do assign :todo, Todo.new(title: "Buy milk") render expect(rendered).to have_css("header h1", text: "Buy milk") end end ``` ## Using Capybara with Test::Unit * If you are using Rails, add the following code in your `test_helper.rb` file to make Capybara available in all test cases deriving from `ActionDispatch::IntegrationTest`: ```ruby class ActionDispatch::IntegrationTest # Make the Capybara DSL available in all integration tests include Capybara::DSL end ``` * If you are not using Rails, define a base class for your Capybara tests like so: ```ruby class CapybaraTestCase < Test::Unit::TestCase include Capybara::DSL def teardown Capybara.reset_sessions! Capybara.use_default_driver end end ``` Remember to call `super` in any subclasses that override `teardown`. To switch the driver, set `Capybara.current_driver`. For instance, ```ruby class BlogTest < ActionDispatch::IntegrationTest setup do Capybara.current_driver = Capybara.javascript_driver # :selenium by default end test 'shows blog posts' do # ... this test is run with Selenium ... end end ``` ## Using Capybara with MiniTest::Spec Set up your base class as with Test::Unit. (On Rails, the right base class could be something other than ActionDispatch::IntegrationTest.) The capybara_minitest_spec gem ([GitHub](https://github.com/ordinaryzelig/capybara_minitest_spec), [rubygems.org](https://rubygems.org/gems/capybara_minitest_spec)) provides MiniTest::Spec expectations for Capybara. For example: ```ruby page.must_have_content('Important!') ``` ## Drivers Capybara uses the same DSL to drive a variety of browser and headless drivers. ### Selecting the Driver By default, Capybara uses the `:rack_test` driver, which is fast but limited: it does not support JavaScript, nor is it able to access HTTP resources outside of your Rack application, such as remote APIs and OAuth services. To get around these limitations, you can set up a different default driver for your features. For example if you'd prefer to run everything in Selenium, you could do: ```ruby Capybara.default_driver = :selenium ``` However, if you are using RSpec or Cucumber, you may instead want to consider leaving the faster `:rack_test` as the __default_driver__, and marking only those tests that require a JavaScript-capable driver using `:js => true` or `@javascript`, respectively. By default, JavaScript tests are run using the `:selenium` driver. You can change this by setting `Capybara.javascript_driver`. You can also change the driver temporarily (typically in the Before/setup and After/teardown blocks): ```ruby Capybara.current_driver = :webkit # temporarily select different driver # tests here Capybara.use_default_driver # switch back to default driver ``` **Note**: switching the driver creates a new session, so you may not be able to switch in the middle of a test. ### RackTest RackTest is Capybara's default driver. It is written in pure Ruby and does not have any support for executing JavaScript. Since the RackTest driver interacts directly with Rack interfaces, it does not require a server to be started. However, this means that if your application is not a Rack application (Rails, Sinatra and most other Ruby frameworks are Rack applications) then you cannot use this driver. Furthermore, you cannot use the RackTest driver to test a remote application, or to access remote URLs (e.g., redirects to external sites, external APIs, or OAuth services) that your application might interact with. [capybara-mechanize](https://github.com/jeroenvandijk/capybara-mechanize) provides a similar driver that can access remote servers. RackTest can be configured with a set of headers like this: ```ruby Capybara.register_driver :rack_test do |app| Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_USER_AGENT' => 'Capybara' }) end ``` See the section on adding and configuring drivers. ### Selenium At the moment, Capybara supports [Selenium 2.0 (Webdriver)](http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver), *not* Selenium RC. In order to use Selenium, you'll need to install the `selenium-webdriver` gem, and add it to your Gemfile if you're using bundler. Provided Firefox is installed, everything is set up for you, and you should be able to start using Selenium right away. **Note**: drivers which run the server in a different thread may not share the same transaction as your tests, causing data not to be shared between your test and test server, see "Transactions and database setup" below. ### Capybara-webkit The [capybara-webkit driver](https://github.com/thoughtbot/capybara-webkit) is for true headless testing. It uses QtWebKit to start a rendering engine process. It can execute JavaScript as well. It is significantly faster than drivers like Selenium since it does not load an entire browser. You can install it with: ```bash gem install capybara-webkit ``` And you can use it by: ```ruby Capybara.javascript_driver = :webkit ``` ### Poltergeist [Poltergeist](https://github.com/jonleighton/poltergeist) is another headless driver which integrates Capybara with [PhantomJS](http://phantomjs.org/). It is truly headless, so doesn't require Xvfb to run on your CI server. It will also detect and report any Javascript errors that happen within the page. ## The DSL *A complete reference is available at [rubydoc.info](http://rubydoc.info/github/jnicklas/capybara/master)*. **Note: By default Capybara will only locate visible elements. This is because a real user would not be able to interact with non-visible elements.** **Note**: All searches in Capybara are *case sensitive*. This is because Capybara heavily uses XPath, which doesn't support case insensitivity. ### Navigating You can use the [visit](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#visit-instance_method) method to navigate to other pages: ```ruby visit('/projects') visit(post_comments_path(post)) ``` The visit method only takes a single parameter, the request method is **always** GET. You can get the [current path](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#current_path-instance_method) of the browsing session for test assertions: ```ruby expect(current_path).to eq(post_comments_path(post)) ``` ### Clicking links and buttons *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions)* You can interact with the webapp by following links and buttons. Capybara automatically follows any redirects, and submits forms associated with buttons. ```ruby click_link('id-of-link') click_link('Link Text') click_button('Save') click_on('Link Text') # clicks on either links or buttons click_on('Button Value') ``` ### Interacting with forms *Full reference: [Capybara::Node::Actions](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Actions)* There are a number of tools for interacting with form elements: ```ruby fill_in('First Name', :with => 'John') fill_in('Password', :with => 'Seekrit') fill_in('Description', :with => 'Really Long Text...') choose('A Radio Button') check('A Checkbox') uncheck('A Checkbox') attach_file('Image', '/path/to/image.jpg') select('Option', :from => 'Select Box') ``` ### Querying *Full reference: [Capybara::Node::Matchers](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers)* Capybara has a rich set of options for querying the page for the existence of certain elements, and working with and manipulating those elements. ```ruby page.has_selector?('table tr') page.has_selector?(:xpath, '//table/tr') page.has_xpath?('//table/tr') page.has_css?('table tr.foo') page.has_content?('foo') ``` **Note:** The negative forms like `has_no_selector?` are different from `not has_selector?`. Read the section on asynchronous JavaScript for an explanation. You can use these with RSpec's magic matchers: ```ruby expect(page).to have_selector('table tr') expect(page).to have_selector(:xpath, '//table/tr') expect(page).to have_xpath('//table/tr') expect(page).to have_css('table tr.foo') expect(page).to have_content('foo') ``` ### Finding _Full reference: [Capybara::Node::Finders](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Finders)_ You can also find specific elements, in order to manipulate them: ```ruby find_field('First Name').value find_link('Hello', :visible => :all).visible? find_button('Send').click find(:xpath, "//table/tr").click find("#overlay").find("h1").click all('a').each { |a| a[:href] } ``` **Note**: `find` will wait for an element to appear on the page, as explained in the Ajax section. If the element does not appear it will raise an error. These elements all have all the Capybara DSL methods available, so you can restrict them to specific parts of the page: ```ruby find('#navigation').click_link('Home') expect(find('#navigation')).to have_button('Sign out') ``` ### Scoping Capybara makes it possible to restrict certain actions, such as interacting with forms or clicking links and buttons, to within a specific area of the page. For this purpose you can use the generic [within](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#within-instance_method) method. Optionally you can specify which kind of selector to use. ```ruby within("li#employee") do fill_in 'Name', :with => 'Jimmy' end within(:xpath, "//li[@id='employee']") do fill_in 'Name', :with => 'Jimmy' end ``` There are special methods for restricting the scope to a specific fieldset, identified by either an id or the text of the fieldset's legend tag, and to a specific table, identified by either id or text of the table's caption tag. ```ruby within_fieldset('Employee') do fill_in 'Name', :with => 'Jimmy' end within_table('Employee') do fill_in 'Name', :with => 'Jimmy' end ``` ### Working with windows Capybara provides some methods to ease finding and switching windows: ```ruby facebook_window = window_opened_by do click_button 'Like' end within_window facebook_window do find('#login_email').set('a@example.com') find('#login_password').set('qwerty') click_button 'Submit' end ``` ### Scripting In drivers which support it, you can easily execute JavaScript: ```ruby page.execute_script("$('body').empty()") ``` For simple expressions, you can return the result of the script. Note that this may break with more complicated expressions: ```ruby result = page.evaluate_script('4 + 4'); ``` ### Modals In drivers which support it, you can accept, dismiss and respond to alerts, confirms and prompts. You can accept or dismiss alert messages by wrapping the code that produces an alert in a block: ```ruby accept_alert do click_link('Show Alert') end ``` You can accept or dismiss a confirmation by wrapping it in a block, as well: ```ruby dismiss_confirm do click_link('Show Confirm') end ``` You can accept or dismiss prompts as well, and also provide text to fill in for the response: ```ruby accept_prompt(with: 'Linus Torvalds') do click_link('Show Prompt About Linux') end ``` All modal methods return the message that was presented. So, you can access the prompt message by assigning the return to a variable: ```ruby message = accept_prompt(with: 'Linus Torvalds') do click_link('Show Prompt About Linux') end expect(message).to eq('Who is the chief architect of Linux?') ``` ### Debugging It can be useful to take a snapshot of the page as it currently is and take a look at it: ```ruby save_and_open_page ``` You can also retrieve the current state of the DOM as a string using [page.html](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#html-instance_method). ```ruby print page.html ``` This is mostly useful for debugging. You should avoid testing against the contents of `page.html` and use the more expressive finder methods instead. Finally, in drivers that support it, you can save a screenshot: ```ruby page.save_screenshot('screenshot.png') ``` Or have it save and automatically open: ```ruby save_and_open_screenshot ``` ## Matching It is possible to customize how Capybara finds elements. At your disposal are two options, `Capybara.exact` and `Capybara.match`. ### Exactness `Capybara.exact` and the `exact` option work together with the `is` expression inside the XPath gem. When `exact` is true, all `is` expressions match exactly, when it is false, they allow substring matches. Many of the selectors built into Capybara use the `is` expression. This way you can specify whether you want to allow substring matches or not. `Capybara.exact` is false by default. For example: ```ruby click_link("Password") # also matches "Password confirmation" Capybara.exact = true click_link("Password") # does not match "Password confirmation" click_link("Password", exact: false) # can be overridden ``` ### Strategy Using `Capybara.match` and the equivalent `match` option, you can control how Capybara behaves when multiple elements all match a query. There are currently four different strategies built into Capybara: 1. **first:** Just picks the first element that matches. 2. **one:** Raises an error if more than one element matches. 3. **smart:** If `exact` is `true`, raises an error if more than one element matches, just like `one`. If `exact` is `false`, it will first try to find an exact match. An error is raised if more than one element is found. If no element is found, a new search is performed which allows partial matches. If that search returns multiple matches, an error is raised. 4. **prefer_exact:** If multiple matches are found, some of which are exact, and some of which are not, then the first exactly matching element is returned. The default for `Capybara.match` is `:smart`. To emulate the behaviour in Capybara 2.0.x, set `Capybara.match` to `:one`. To emulate the behaviour in Capybara 1.x, set `Capybara.match` to `:prefer_exact`. ## Transactions and database setup Some Capybara drivers need to run against an actual HTTP server. Capybara takes care of this and starts one for you in the same process as your test, but on another thread. Selenium is one of those drivers, whereas RackTest is not. If you are using a SQL database, it is common to run every test in a transaction, which is rolled back at the end of the test, rspec-rails does this by default out of the box for example. Since transactions are usually not shared across threads, this will cause data you have put into the database in your test code to be invisible to Capybara. Cucumber handles this by using truncation instead of transactions, i.e. they empty out the entire database after each test. You can get the same behaviour by using a gem such as [database_cleaner](https://github.com/bmabey/database_cleaner). It is also possible to force your ORM to use the same transaction for all threads. This may have thread safety implications and could cause strange failures, so use caution with this approach. It can be implemented in ActiveRecord through the following monkey patch: ```ruby class ActiveRecord::Base mattr_accessor :shared_connection @@shared_connection = nil def self.connection @@shared_connection || retrieve_connection end end ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection ``` ## Asynchronous JavaScript (Ajax and friends) When working with asynchronous JavaScript, you might come across situations where you are attempting to interact with an element which is not yet present on the page. Capybara automatically deals with this by waiting for elements to appear on the page. When issuing instructions to the DSL such as: ```ruby click_link('foo') click_link('bar') expect(page).to have_content('baz') ``` If clicking on the *foo* link triggers an asynchronous process, such as an Ajax request, which, when complete will add the *bar* link to the page, clicking on the *bar* link would be expected to fail, since that link doesn't exist yet. However Capybara is smart enough to retry finding the link for a brief period of time before giving up and throwing an error. The same is true of the next line, which looks for the content *baz* on the page; it will retry looking for that content for a brief time. You can adjust how long this period is (the default is 2 seconds): ```ruby Capybara.default_max_wait_time = 5 ``` Be aware that because of this behaviour, the following two statements are **not** equivalent, and you should **always** use the latter! ```ruby !page.has_xpath?('a') page.has_no_xpath?('a') ``` The former would immediately fail because the content has not yet been removed. Only the latter would wait for the asynchronous process to remove the content from the page. Capybara's Rspec matchers, however, are smart enough to handle either form. The two following statements are functionally equivalent: ```ruby expect(page).not_to have_xpath('a') expect(page).to have_no_xpath('a') ``` Capybara's waiting behaviour is quite advanced, and can deal with situations such as the following line of code: ```ruby expect(find('#sidebar').find('h1')).to have_content('Something') ``` Even if JavaScript causes `#sidebar` to disappear off the page, Capybara will automatically reload it and any elements it contains. So if an AJAX request causes the contents of `#sidebar` to change, which would update the text of the `h1` to "Something", and this happened, this test would pass. If you do not want this behaviour, you can set `Capybara.automatic_reload` to `false`. ## Using the DSL elsewhere You can mix the DSL into any context by including Capybara::DSL: ```ruby require 'capybara' require 'capybara/dsl' Capybara.default_driver = :webkit module MyModule include Capybara::DSL def login! within("//form[@id='session']") do fill_in 'Email', :with => 'user@example.com' fill_in 'Password', :with => 'password' end click_button 'Sign in' end end ``` This enables its use in unsupported testing frameworks, and for general-purpose scripting. ## Calling remote servers Normally Capybara expects to be testing an in-process Rack application, but you can also use it to talk to a web server running anywhere on the internet, by setting app_host: ```ruby Capybara.current_driver = :selenium Capybara.app_host = 'http://www.google.com' ... visit('/') ``` **Note**: the default driver (`:rack_test`) does not support running against a remote server. With drivers that support it, you can also visit any URL directly: ```ruby visit('http://www.google.com') ``` By default Capybara will try to boot a rack application automatically. You might want to switch off Capybara's rack server if you are running against a remote application: ```ruby Capybara.run_server = false ``` ## Using the sessions manually For ultimate control, you can instantiate and use a [Session](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session) manually. ```ruby require 'capybara' session = Capybara::Session.new(:webkit, my_rack_app) session.within("//form[@id='session']") do session.fill_in 'Email', :with => 'user@example.com' session.fill_in 'Password', :with => 'password' end session.click_button 'Sign in' ``` ## XPath, CSS and selectors Capybara does not try to guess what kind of selector you are going to give it, and will always use CSS by default. If you want to use XPath, you'll need to do: ```ruby within(:xpath, '//ul/li') { ... } find(:xpath, '//ul/li').text find(:xpath, '//li[contains(.//a[@href = "#"]/text(), "foo")]').value ``` Alternatively you can set the default selector to XPath: ```ruby Capybara.default_selector = :xpath find('//ul/li').text ``` Capybara allows you to add custom selectors, which can be very useful if you find yourself using the same kinds of selectors very often: ```ruby Capybara.add_selector(:id) do xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] } end Capybara.add_selector(:row) do xpath { |num| ".//tbody/tr[#{num}]" } end Capybara.add_selector(:flash_type) do css { |type| "#flash.#{type}" } end ``` The block given to xpath must always return an XPath expression as a String, or an XPath expression generated through the XPath gem. You can now use these selectors like this: ```ruby find(:id, 'post_123') find(:row, 3) find(:flash_type, :notice) ``` ## Beware the XPath // trap In XPath the expression // means something very specific, and it might not be what you think. Contrary to common belief, // means "anywhere in the document" not "anywhere in the current context". As an example: ```ruby page.find(:xpath, '//body').all(:xpath, '//script') ``` You might expect this to find all script tags in the body, but actually, it finds all script tags in the entire document, not only those in the body! What you're looking for is the .// expression which means "any descendant of the current node": ```ruby page.find(:xpath, '//body').all(:xpath, './/script') ``` The same thing goes for within: ```ruby within(:xpath, '//body') do page.find(:xpath, './/script') within(:xpath, './/table/tbody') do ... end end ``` ## Configuring and adding drivers Capybara makes it convenient to switch between different drivers. It also exposes an API to tweak those drivers with whatever settings you want, or to add your own drivers. This is how to override the selenium driver configuration to use chrome: ```ruby Capybara.register_driver :selenium do |app| Capybara::Selenium::Driver.new(app, :browser => :chrome) end ``` However, it's also possible to give this configuration a different name. ```ruby Capybara.register_driver :selenium_chrome do |app| Capybara::Selenium::Driver.new(app, :browser => :chrome) end ``` Then tests can switch between using different browsers effortlessly: ```ruby Capybara.current_driver = :selenium_chrome ``` Whatever is returned from the block should conform to the API described by Capybara::Driver::Base, it does not however have to inherit from this class. Gems can use this API to add their own drivers to Capybara. The [Selenium wiki](http://code.google.com/p/selenium/wiki/RubyBindings) has additional info about how the underlying driver can be configured. ## Gotchas: * Access to session and request is not possible from the test, Access to response is limited. Some drivers allow access to response headers and HTTP status code, but this kind of functionality is not provided by some drivers, such as Selenium. * Access to Rails specific stuff (such as `controller`) is unavailable, since we're not using Rails' integration testing. * Freezing time: It's common practice to mock out the Time so that features that depend on the current Date work as expected. This can be problematic on ruby/platform combinations that don't support access to a monotonic process clock, since Capybara's Ajax timing uses the system time, resulting in Capybara never timing out and just hanging when a failure occurs. It's still possible to use gems which allow you to travel in time, rather than freeze time. One such gem is [Timecop](http://github.com/travisjeffery/timecop). * When using Rack::Test, beware if attempting to visit absolute URLs. For example, a session might not be shared between visits to `posts_path` and `posts_url`. If testing an absolute URL in an Action Mailer email, set `default_url_options` to match the Rails default of `www.example.com`. * Server errors will only be raised in the session that initiates the server thread. If you are testing for specific server errors and using multiple sessions make sure to test for the errors using the initial session (usually :default) ## Development To set up a development environment, simply do: ```bash bundle install bundle exec rake # run the test suite ``` See [CONTRIBUTING.md](https://github.com/jnicklas/capybara/blob/master/CONTRIBUTING.md) for how to send issues and pull requests. capybara-2.5.0/metadata.yml0000644000175000017500000003013612573712570014643 0ustar lunarlunar--- !ruby/object:Gem::Specification name: capybara version: !ruby/object:Gem::Version version: 2.5.0 platform: ruby authors: - Jonas Nicklas autorequire: bindir: bin cert_chain: - gem-public_cert.pem date: 2015-08-26 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: nokogiri requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.3.3 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.3.3 - !ruby/object:Gem::Dependency name: mime-types requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '1.16' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '1.16' - !ruby/object:Gem::Dependency name: rack requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.0.0 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.0.0 - !ruby/object:Gem::Dependency name: rack-test requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.5.4 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.5.4 - !ruby/object:Gem::Dependency name: xpath requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '2.0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '2.0' - !ruby/object:Gem::Dependency name: selenium-webdriver requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '2.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '2.0' - !ruby/object:Gem::Dependency name: sinatra requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.9.4 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.9.4 - !ruby/object:Gem::Dependency name: rspec requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.2.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.2.0 - !ruby/object:Gem::Dependency name: launchy requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.0.4 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.0.4 - !ruby/object:Gem::Dependency name: yard requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.5.8 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.5.8 - !ruby/object:Gem::Dependency name: fuubar requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.0.1 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.0.1 - !ruby/object:Gem::Dependency name: cucumber requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.10.5 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 0.10.5 - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: pry requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' description: Capybara is an integration testing tool for rack based web applications. It simulates how a user would interact with a website email: - jonas.nicklas@gmail.com executables: [] extensions: [] extra_rdoc_files: [] files: - History.md - License.txt - README.md - lib/capybara.rb - lib/capybara/cucumber.rb - lib/capybara/driver/base.rb - lib/capybara/driver/node.rb - lib/capybara/dsl.rb - lib/capybara/helpers.rb - lib/capybara/node/actions.rb - lib/capybara/node/base.rb - lib/capybara/node/document.rb - lib/capybara/node/document_matchers.rb - lib/capybara/node/element.rb - lib/capybara/node/finders.rb - lib/capybara/node/matchers.rb - lib/capybara/node/simple.rb - lib/capybara/queries/base_query.rb - lib/capybara/queries/current_path_query.rb - lib/capybara/queries/text_query.rb - lib/capybara/queries/title_query.rb - lib/capybara/query.rb - lib/capybara/rack_test/browser.rb - lib/capybara/rack_test/css_handlers.rb - lib/capybara/rack_test/driver.rb - lib/capybara/rack_test/form.rb - lib/capybara/rack_test/node.rb - lib/capybara/rails.rb - lib/capybara/result.rb - lib/capybara/rspec.rb - lib/capybara/rspec/features.rb - lib/capybara/rspec/matchers.rb - lib/capybara/selector.rb - lib/capybara/selenium/driver.rb - lib/capybara/selenium/node.rb - lib/capybara/server.rb - lib/capybara/session.rb - lib/capybara/session/matchers.rb - lib/capybara/spec/fixtures/another_test_file.txt - lib/capybara/spec/fixtures/capybara.jpg - lib/capybara/spec/fixtures/test_file.txt - lib/capybara/spec/public/jquery-ui.js - lib/capybara/spec/public/jquery.js - lib/capybara/spec/public/test.js - lib/capybara/spec/session/accept_alert_spec.rb - lib/capybara/spec/session/accept_confirm_spec.rb - lib/capybara/spec/session/accept_prompt_spec.rb - lib/capybara/spec/session/all_spec.rb - lib/capybara/spec/session/assert_current_path.rb - lib/capybara/spec/session/assert_selector.rb - lib/capybara/spec/session/assert_text.rb - lib/capybara/spec/session/assert_title.rb - lib/capybara/spec/session/attach_file_spec.rb - lib/capybara/spec/session/body_spec.rb - lib/capybara/spec/session/check_spec.rb - lib/capybara/spec/session/choose_spec.rb - lib/capybara/spec/session/click_button_spec.rb - lib/capybara/spec/session/click_link_or_button_spec.rb - lib/capybara/spec/session/click_link_spec.rb - lib/capybara/spec/session/current_scope_spec.rb - lib/capybara/spec/session/current_url_spec.rb - lib/capybara/spec/session/dismiss_confirm_spec.rb - lib/capybara/spec/session/dismiss_prompt_spec.rb - lib/capybara/spec/session/evaluate_script_spec.rb - lib/capybara/spec/session/execute_script_spec.rb - lib/capybara/spec/session/fill_in_spec.rb - lib/capybara/spec/session/find_button_spec.rb - lib/capybara/spec/session/find_by_id_spec.rb - lib/capybara/spec/session/find_field_spec.rb - lib/capybara/spec/session/find_link_spec.rb - lib/capybara/spec/session/find_spec.rb - lib/capybara/spec/session/first_spec.rb - lib/capybara/spec/session/go_back_spec.rb - lib/capybara/spec/session/go_forward_spec.rb - lib/capybara/spec/session/has_button_spec.rb - lib/capybara/spec/session/has_css_spec.rb - lib/capybara/spec/session/has_current_path_spec.rb - lib/capybara/spec/session/has_field_spec.rb - lib/capybara/spec/session/has_link_spec.rb - lib/capybara/spec/session/has_select_spec.rb - lib/capybara/spec/session/has_selector_spec.rb - lib/capybara/spec/session/has_table_spec.rb - lib/capybara/spec/session/has_text_spec.rb - lib/capybara/spec/session/has_title_spec.rb - lib/capybara/spec/session/has_xpath_spec.rb - lib/capybara/spec/session/headers.rb - lib/capybara/spec/session/html_spec.rb - lib/capybara/spec/session/node_spec.rb - lib/capybara/spec/session/reset_session_spec.rb - lib/capybara/spec/session/response_code.rb - lib/capybara/spec/session/save_and_open_page_spec.rb - lib/capybara/spec/session/save_and_open_screenshot_spec.rb - lib/capybara/spec/session/save_page_spec.rb - lib/capybara/spec/session/save_screenshot_spec.rb - lib/capybara/spec/session/screenshot_spec.rb - lib/capybara/spec/session/select_spec.rb - lib/capybara/spec/session/source_spec.rb - lib/capybara/spec/session/text_spec.rb - lib/capybara/spec/session/title_spec.rb - lib/capybara/spec/session/uncheck_spec.rb - lib/capybara/spec/session/unselect_spec.rb - lib/capybara/spec/session/visit_spec.rb - lib/capybara/spec/session/window/become_closed_spec.rb - lib/capybara/spec/session/window/current_window_spec.rb - lib/capybara/spec/session/window/open_new_window_spec.rb - lib/capybara/spec/session/window/switch_to_window_spec.rb - lib/capybara/spec/session/window/window_opened_by_spec.rb - lib/capybara/spec/session/window/window_spec.rb - lib/capybara/spec/session/window/windows_spec.rb - lib/capybara/spec/session/window/within_window_spec.rb - lib/capybara/spec/session/within_frame_spec.rb - lib/capybara/spec/session/within_spec.rb - lib/capybara/spec/spec_helper.rb - lib/capybara/spec/test_app.rb - lib/capybara/spec/views/buttons.erb - lib/capybara/spec/views/fieldsets.erb - lib/capybara/spec/views/form.erb - lib/capybara/spec/views/frame_child.erb - lib/capybara/spec/views/frame_one.erb - lib/capybara/spec/views/frame_parent.erb - lib/capybara/spec/views/frame_two.erb - lib/capybara/spec/views/header_links.erb - lib/capybara/spec/views/host_links.erb - lib/capybara/spec/views/path.erb - lib/capybara/spec/views/popup_one.erb - lib/capybara/spec/views/popup_two.erb - lib/capybara/spec/views/postback.erb - lib/capybara/spec/views/tables.erb - lib/capybara/spec/views/with_base_tag.erb - lib/capybara/spec/views/with_count.erb - lib/capybara/spec/views/with_hover.erb - lib/capybara/spec/views/with_html.erb - lib/capybara/spec/views/with_html_entities.erb - lib/capybara/spec/views/with_js.erb - lib/capybara/spec/views/with_scope.erb - lib/capybara/spec/views/with_simple_html.erb - lib/capybara/spec/views/with_title.erb - lib/capybara/spec/views/with_windows.erb - lib/capybara/spec/views/within_frames.erb - lib/capybara/version.rb - lib/capybara/window.rb - spec/basic_node_spec.rb - spec/capybara_spec.rb - spec/dsl_spec.rb - spec/fixtures/selenium_driver_rspec_failure.rb - spec/fixtures/selenium_driver_rspec_success.rb - spec/rack_test_spec.rb - spec/result_spec.rb - spec/rspec/features_spec.rb - spec/rspec/matchers_spec.rb - spec/rspec/views_spec.rb - spec/rspec_spec.rb - spec/selenium_spec.rb - spec/selenium_spec_chrome.rb - spec/server_spec.rb - spec/spec_helper.rb homepage: http://github.com/jnicklas/capybara licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.9.3 required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.4.5.1 signing_key: specification_version: 4 summary: Capybara aims to simplify the process of integration testing Rack applications, such as Rails, Sinatra or Merb test_files: [] has_rdoc: capybara-2.5.0/spec/0000755000175000017500000000000012573712570013267 5ustar lunarlunarcapybara-2.5.0/spec/capybara_spec.rb0000644000175000017500000000402212573712570016406 0ustar lunarlunarrequire 'spec_helper' RSpec.describe Capybara do describe 'default_max_wait_time' do after do Capybara.default_max_wait_time = @previous_default_time end it "should be changeable" do @previous_default_time = Capybara.default_max_wait_time Capybara.default_max_wait_time = 5 expect(Capybara.default_max_wait_time).to eq(5) end it "should be accesible as the deprecated default_wait_time" do expect_any_instance_of(Kernel).to receive(:warn).once.with('DEPRECATED: #default_wait_time= is deprecated, please use #default_max_wait_time= instead') expect_any_instance_of(Kernel).to receive(:warn).once.with('DEPRECATED: #default_wait_time is deprecated, please use #default_max_wait_time instead') @previous_default_time = Capybara.default_max_wait_time Capybara.default_wait_time = 5 expect(Capybara.default_wait_time).to eq(5) expect(Capybara.default_max_wait_time).to eq(5) end end describe '.register_driver' do it "should add a new driver" do Capybara.register_driver :schmoo do |app| Capybara::RackTest::Driver.new(app) end session = Capybara::Session.new(:schmoo, TestApp) session.visit('/') expect(session.body).to include("Hello world!") end end describe ".server" do after do Capybara.server {|app, port| Capybara.run_default_server(app, port)} end it "should default to a proc that calls run_default_server" do mock_app = double('app') expect(Capybara).to receive(:run_default_server).with(mock_app, 8000) Capybara.server.call(mock_app, 8000) end it "should return a custom server proc" do server = lambda {|app, port|} Capybara.server(&server) expect(Capybara.server).to eq(server) end end end RSpec.describe Capybara::Session do context 'with non-existant driver' do it "should raise an error" do expect { Capybara::Session.new(:quox, TestApp).driver }.to raise_error(Capybara::DriverNotFoundError) end end end capybara-2.5.0/spec/selenium_spec_chrome.rb0000644000175000017500000000077312573712570020013 0ustar lunarlunarrequire 'spec_helper' require 'selenium-webdriver' Capybara.register_driver :selenium_chrome do |app| args = ENV['TRAVIS'] ? ['no-sandbox' ] : [] Capybara::Selenium::Driver.new(app, :browser => :chrome, :args => args) end module TestSessions Chrome = Capybara::Session.new(:selenium_chrome, TestApp) end Capybara::SpecHelper.run_specs TestSessions::Chrome, "selenium_chrome", :capybara_skip => [ :response_headers, :status_code, :trigger ] unless ENV['TRAVIS'] && (RUBY_PLATFORM == 'java') capybara-2.5.0/spec/rspec_spec.rb0000644000175000017500000000260312573712570015743 0ustar lunarlunarrequire 'spec_helper' RSpec.describe 'capybara/rspec', :type => :feature do it "should include Capybara in rspec" do visit('/foo') expect(page.body).to include('Another World') end context "resetting session" do it "sets a cookie in one example..." do visit('/set_cookie') expect(page.body).to include('Cookie set to test_cookie') end it "...then it is not available in the next" do visit('/get_cookie') expect(page.body).not_to include('test_cookie') end end context "setting the current driver" do it "sets the current driver in one example..." do Capybara.current_driver = :selenium end it "...then it has returned to the default in the next example" do expect(Capybara.current_driver).to eq(:rack_test) end end it "switches to the javascript driver when giving it as metadata", :js => true do expect(Capybara.current_driver).to eq(Capybara.javascript_driver) end it "switches to the given driver when giving it as metadata", :driver => :culerity do expect(Capybara.current_driver).to eq(:culerity) end end RSpec.describe 'capybara/rspec', :type => :other do it "should not include Capybara" do expect { visit('/') }.to raise_error(NoMethodError) end end feature "Feature DSL" do scenario "is pulled in" do visit('/foo') expect(page.body).to include('Another World') end end capybara-2.5.0/spec/rack_test_spec.rb0000644000175000017500000001310712573712570016607 0ustar lunarlunarrequire 'spec_helper' module TestSessions RackTest = Capybara::Session.new(:rack_test, TestApp) end Capybara::SpecHelper.run_specs TestSessions::RackTest, "RackTest", :capybara_skip => [ :js, :modals, :screenshot, :frames, :windows, :send_keys, :server, :hover, :about_scheme, ] RSpec.describe Capybara::Session do context 'with rack test driver' do before do @session = TestSessions::RackTest end describe '#driver' do it "should be a rack test driver" do expect(@session.driver).to be_an_instance_of(Capybara::RackTest::Driver) end end describe '#mode' do it "should remember the mode" do expect(@session.mode).to eq(:rack_test) end end describe '#click_link' do it "should use data-method if option is true" do @session.driver.options[:respect_data_method] = true @session.visit "/with_html" @session.click_link "A link with data-method" expect(@session.html).to include('The requested object was deleted') end it "should not use data-method if option is false" do @session.driver.options[:respect_data_method] = false @session.visit "/with_html" @session.click_link "A link with data-method" expect(@session.html).to include('Not deleted') end it "should use data-method if available even if it's capitalized" do @session.driver.options[:respect_data_method] = true @session.visit "/with_html" @session.click_link "A link with capitalized data-method" expect(@session.html).to include('The requested object was deleted') end after do @session.driver.options[:respect_data_method] = false end end describe "#fill_in" do it "should warn that :fill_options are not supported" do expect_any_instance_of(Capybara::Node::Element).to receive(:warn) .with("Options passed to Capybara::Node#set but the driver doesn't support them") @session.visit "/with_html" @session.fill_in 'test_field', with: 'not_moneky', fill_options: { random: true } end end describe "#attach_file" do context "with multipart form" do it "should submit an empty form-data section if no file is submitted" do @session.visit("/form") @session.click_button("Upload Empty") expect(@session.html).to include('Successfully ignored empty file field.') end end end end end RSpec.describe Capybara::RackTest::Driver do before do @driver = TestSessions::RackTest.driver end describe ':headers option' do it 'should always set headers' do @driver = Capybara::RackTest::Driver.new(TestApp, :headers => {'HTTP_FOO' => 'foobar'}) @driver.visit('/get_header') expect(@driver.html).to include('foobar') end it 'should keep headers on link clicks' do @driver = Capybara::RackTest::Driver.new(TestApp, :headers => {'HTTP_FOO' => 'foobar'}) @driver.visit('/header_links') @driver.find_xpath('.//a').first.click expect(@driver.html).to include('foobar') end it 'should keep headers on form submit' do @driver = Capybara::RackTest::Driver.new(TestApp, :headers => {'HTTP_FOO' => 'foobar'}) @driver.visit('/header_links') @driver.find_xpath('.//input').first.click expect(@driver.html).to include('foobar') end it 'should keep headers on redirects' do @driver = Capybara::RackTest::Driver.new(TestApp, :headers => {'HTTP_FOO' => 'foobar'}) @driver.visit('/get_header_via_redirect') expect(@driver.html).to include('foobar') end end describe ':follow_redirects option' do it "defaults to following redirects" do @driver = Capybara::RackTest::Driver.new(TestApp) @driver.visit('/redirect') expect(@driver.response.header['Location']).to be_nil expect(@driver.current_url).to match %r{/landed$} end it "is possible to not follow redirects" do @driver = Capybara::RackTest::Driver.new(TestApp, :follow_redirects => false) @driver.visit('/redirect') expect(@driver.response.header['Location']).to match %r{/redirect_again$} expect(@driver.current_url).to match %r{/redirect$} end end describe ':redirect_limit option' do context "with default redirect limit" do before do @driver = Capybara::RackTest::Driver.new(TestApp) end it "should follow 5 redirects" do @driver.visit("/redirect/5/times") expect(@driver.html).to include('redirection complete') end it "should not follow more than 6 redirects" do expect do @driver.visit("/redirect/6/times") end.to raise_error(Capybara::InfiniteRedirectError) end end context "with 21 redirect limit" do before do @driver = Capybara::RackTest::Driver.new(TestApp, :redirect_limit => 21) end it "should follow 21 redirects" do @driver.visit("/redirect/21/times") expect(@driver.html).to include('redirection complete') end it "should not follow more than 21 redirects" do expect do @driver.visit("/redirect/22/times") end.to raise_error(Capybara::InfiniteRedirectError) end end end end module CSSHandlerIncludeTester def dont_extend_css_handler raise 'should never be called' end end include CSSHandlerIncludeTester RSpec.describe Capybara::RackTest::CSSHandlers do it "should not be extended by global includes" do expect(Capybara::RackTest::CSSHandlers.new).not_to respond_to(:dont_extend_css_handler) end end capybara-2.5.0/spec/selenium_spec.rb0000644000175000017500000001006412573712570016450 0ustar lunarlunarrequire 'spec_helper' require "selenium-webdriver" Capybara.register_driver :selenium_focus do |app| profile = Selenium::WebDriver::Firefox::Profile.new profile["focusmanager.testmode"] = true Capybara::Selenium::Driver.new(app, browser: :firefox, profile: profile) end module TestSessions Selenium = Capybara::Session.new(:selenium_focus, TestApp) end Capybara::SpecHelper.run_specs TestSessions::Selenium, "selenium", :capybara_skip => [ :response_headers, :status_code, :trigger ] RSpec.describe Capybara::Session do context 'with selenium driver' do before do @session = TestSessions::Selenium end describe '#driver' do it "should be a selenium driver" do expect(@session.driver).to be_an_instance_of(Capybara::Selenium::Driver) end end describe '#mode' do it "should remember the mode" do expect(@session.mode).to eq(:selenium_focus) end end describe "#reset!" do it "freshly reset session should not be touched" do @session.instance_variable_set(:@touched, true) @session.reset! expect(@session.instance_variable_get(:@touched)).to eq false end end describe "exit codes" do before do @current_dir = Dir.getwd Dir.chdir(File.join(File.dirname(__FILE__), '..')) end after do Dir.chdir(@current_dir) end it "should have return code 1 when running selenium_driver_rspec_failure.rb" do `rspec spec/fixtures/selenium_driver_rspec_failure.rb` expect($?.exitstatus).to be 1 end it "should have return code 0 when running selenium_driver_rspec_success.rb" do `rspec spec/fixtures/selenium_driver_rspec_success.rb` expect($?.exitstatus).to be 0 end end describe "#accept_alert" do it "supports a blockless mode" do @session.visit('/with_js') @session.click_link('Open alert') @session.accept_alert expect{@session.driver.browser.switch_to.alert}.to raise_error("No alert is present") end end context "#fill_in with { :clear => :backspace } fill_option", :requires => [:js] do it 'should fill in a field, replacing an existing value' do @session.visit('/form') @session.fill_in('form_first_name', :with => 'Harry', fill_options: { clear: :backspace} ) expect(@session.find(:fillable_field, 'form_first_name').value).to eq('Harry') end it 'should only trigger onchange once' do @session.visit('/with_js') @session.fill_in('with_change_event', :with => 'some value', :fill_options => { :clear => :backspace }) # click outside the field to trigger the change event @session.find(:css, 'body').click expect(@session.find(:css, '.change_event_triggered', :match => :one)).to have_text 'some value' end it 'should trigger change when clearing field' do @session.visit('/with_js') @session.fill_in('with_change_event', :with => '', :fill_options => { :clear => :backspace }) # click outside the field to trigger the change event @session.find(:css, 'body').click expect(@session).to have_selector(:css, '.change_event_triggered', :match => :one) end end describe "#path" do it "returns xpath" do # this is here because it is testing for an XPath that is specific to the algorithm used in the selenium driver @session.visit('/path') element = @session.find(:link, 'Second Link') expect(element.path).to eq('/html/body/div[2]/a[1]') end end end end RSpec.describe Capybara::Selenium::Driver do before do @driver = Capybara::Selenium::Driver.new(TestApp, browser: :firefox) end describe '#quit' do it "should reset browser when quit" do expect(@driver.browser).to be @driver.quit #access instance variable directly so we don't create a new browser instance expect(@driver.instance_variable_get(:@browser)).to be_nil end end end capybara-2.5.0/spec/spec_helper.rb0000644000175000017500000000023112573712570016101 0ustar lunarlunarrequire 'rspec/expectations' require "capybara/spec/spec_helper" require "pry" RSpec.configure do |config| Capybara::SpecHelper.configure(config) end capybara-2.5.0/spec/basic_node_spec.rb0000644000175000017500000001101612573712570016713 0ustar lunarlunarrequire 'spec_helper' RSpec.describe Capybara do describe '.string' do let :string do Capybara.string <<-STRING simple_node not document title

Totally awesome

Yes it is

STRING end it "allows using matchers" do expect(string).to have_css('#page') expect(string).not_to have_css('#does-not-exist') end it "allows using custom matchers" do Capybara.add_selector :lifeform do xpath { |name| "//option[contains(.,'#{name}')]" } end expect(string).to have_selector(:id, "page") expect(string).not_to have_selector(:id, 'does-not-exist') expect(string).to have_selector(:lifeform, "Monkey") expect(string).not_to have_selector(:lifeform, "Gorilla") end it 'allows custom matcher using css' do Capybara.add_selector :section do css { |css_class| "section .#{css_class}" } end expect(string).to have_selector(:section, 'subsection') expect(string).not_to have_selector(:section, 'section_8') end it "allows using matchers with text option" do expect(string).to have_css('h1', :text => 'Totally awesome') expect(string).not_to have_css('h1', :text => 'Not so awesome') end it "allows finding only visible nodes" do expect(string.all(:css, '#secret', :visible => true)).to be_empty expect(string.all(:css, '#secret', :visible => false).size).to eq(1) end it "allows finding elements and extracting text from them" do expect(string.find('//h1').text).to eq('Totally awesome') end it "allows finding elements and extracting attributes from them" do expect(string.find('//h1')[:data]).to eq('fantastic') end it "allows finding elements and extracting the tag name from them" do expect(string.find('//h1').tag_name).to eq('h1') end it "allows finding elements and extracting the path" do expect(string.find('//h1').path).to eq('/html/body/div/div[1]/h1') end it "allows finding elements and extracting the path" do expect(string.find('//div/input').value).to eq('bar') expect(string.find('//select').value).to eq('Capybara') end it "allows finding elements and checking if they are visible" do expect(string.find('//h1')).to be_visible expect(string.find(:css, "#secret", :visible => false)).not_to be_visible end it "allows finding elements and checking if they are disabled" do expect(string.find('//form/input[@name="bleh"]')).to be_disabled expect(string.find('//form/input[@name="meh"]')).not_to be_disabled end describe "#title" do it "returns the page title" do expect(string.title).to eq("simple_node") end end describe "#has_title?" do it "returns whether the page has the given title" do expect(string.has_title?('simple_node')).to be_truthy expect(string.has_title?('monkey')).to be_falsey end it "allows regexp matches" do expect(string.has_title?(/s[a-z]+_node/)).to be_truthy expect(string.has_title?(/monkey/)).to be_falsey end end describe '#has_no_title?' do it "returns whether the page does not have the given title" do expect(string.has_no_title?('simple_node')).to be_falsey expect(string.has_no_title?('monkey')).to be_truthy end it "allows regexp matches" do expect(string.has_no_title?(/s[a-z]+_node/)).to be_falsey expect(string.has_no_title?(/monkey/)).to be_truthy end end end end capybara-2.5.0/spec/server_spec.rb0000644000175000017500000000724212573712570016141 0ustar lunarlunarrequire 'spec_helper' RSpec.describe Capybara::Server do it "should spool up a rack server" do @app = proc { |env| [200, {}, ["Hello Server!"]]} @server = Capybara::Server.new(@app).boot @res = Net::HTTP.start(@server.host, @server.port) { |http| http.get('/') } expect(@res.body).to include('Hello Server') end it "should do nothing when no server given" do expect do @server = Capybara::Server.new(nil).boot end.not_to raise_error end it "should bind to the specified host" do begin app = proc { |env| [200, {}, ['Hello Server!']] } Capybara.server_host = '127.0.0.1' server = Capybara::Server.new(app).boot res = Net::HTTP.get(URI("http://127.0.0.1:#{server.port}")) expect(res).to eq('Hello Server!') Capybara.server_host = '0.0.0.0' server = Capybara::Server.new(app).boot res = Net::HTTP.get(URI("http://127.0.0.1:#{server.port}")) expect(res).to eq('Hello Server!') ensure Capybara.server_host = nil end end it "should use specified port" do Capybara.server_port = 22789 @app = proc { |env| [200, {}, ["Hello Server!"]]} @server = Capybara::Server.new(@app).boot @res = Net::HTTP.start(@server.host, 22789) { |http| http.get('/') } expect(@res.body).to include('Hello Server') Capybara.server_port = nil end it "should use given port" do @app = proc { |env| [200, {}, ["Hello Server!"]]} @server = Capybara::Server.new(@app, 22790).boot @res = Net::HTTP.start(@server.host, 22790) { |http| http.get('/') } expect(@res.body).to include('Hello Server') Capybara.server_port = nil end it "should find an available port" do @app1 = proc { |env| [200, {}, ["Hello Server!"]]} @app2 = proc { |env| [200, {}, ["Hello Second Server!"]]} @server1 = Capybara::Server.new(@app1).boot @server2 = Capybara::Server.new(@app2).boot @res1 = Net::HTTP.start(@server1.host, @server1.port) { |http| http.get('/') } expect(@res1.body).to include('Hello Server') @res2 = Net::HTTP.start(@server2.host, @server2.port) { |http| http.get('/') } expect(@res2.body).to include('Hello Second Server') end it "should use the server if it already running" do @app1 = proc { |env| [200, {}, ["Hello Server!"]]} @app2 = proc { |env| [200, {}, ["Hello Second Server!"]]} @server1a = Capybara::Server.new(@app1).boot @server1b = Capybara::Server.new(@app1).boot @server2a = Capybara::Server.new(@app2).boot @server2b = Capybara::Server.new(@app2).boot @res1 = Net::HTTP.start(@server1b.host, @server1b.port) { |http| http.get('/') } expect(@res1.body).to include('Hello Server') @res2 = Net::HTTP.start(@server2b.host, @server2b.port) { |http| http.get('/') } expect(@res2.body).to include('Hello Second Server') expect(@server1a.port).to eq(@server1b.port) expect(@server2a.port).to eq(@server2b.port) end it "should raise server errors when the server errors before the timeout" do begin Capybara.server do sleep 0.1 raise 'kaboom' end expect do Capybara::Server.new(proc {|e|}).boot end.to raise_error(RuntimeError, 'kaboom') ensure # TODO refactor out the defaults so it's reliant on unset state instead of # a one-time call in capybara.rb Capybara.server {|app, port| Capybara.run_default_server(app, port)} end end it "is not #responsive? when Net::HTTP raises a SystemCallError" do app = lambda { [200, {}, ['Hello, world']] } server = Capybara::Server.new(app) expect(Net::HTTP).to receive(:start).and_raise(SystemCallError.allocate) expect(server.responsive?).to eq false end end capybara-2.5.0/spec/result_spec.rb0000644000175000017500000000240512573712570016145 0ustar lunarlunarrequire 'spec_helper' RSpec.describe Capybara::Result do let :string do Capybara.string <<-STRING STRING end let :result do string.all '//li' end it "has a length" do expect(result.length).to eq(4) end it "has a first element" do result.first.text == 'Alpha' end it "has a last element" do result.last.text == 'Delta' end it 'can supports values_at method' do expect(result.values_at(0, 2).map(&:text)).to eq(%w(Alpha Gamma)) end it "can return an element by its index" do expect(result.at(1).text).to eq('Beta') expect(result[2].text).to eq('Gamma') end it "can be mapped" do expect(result.map(&:text)).to eq(%w(Alpha Beta Gamma Delta)) end it "can be selected" do expect(result.select do |element| element.text.include? 't' end.length).to eq(2) end it "can be reduced" do expect(result.reduce('') do |memo, element| memo += element.text[0] end).to eq('ABGD') end it 'can be sampled' do expect(result).to include(result.sample) end it 'can be indexed' do expect(result.index do |el| el.text == 'Gamma' end).to eq(2) end end capybara-2.5.0/spec/dsl_spec.rb0000644000175000017500000001740612573712570015420 0ustar lunarlunarrequire 'spec_helper' require 'capybara/dsl' class TestClass include Capybara::DSL end Capybara::SpecHelper.run_specs TestClass.new, "DSL", :capybara_skip => [ :js, :modals, :screenshot, :frames, :windows, :send_keys, :server, :hover, :about_scheme, ] RSpec.describe Capybara::DSL do after do Capybara.session_name = nil Capybara.default_driver = nil Capybara.javascript_driver = nil Capybara.use_default_driver Capybara.app = TestApp end describe '#default_driver' do it "should default to rack_test" do expect(Capybara.default_driver).to eq(:rack_test) end it "should be changeable" do Capybara.default_driver = :culerity expect(Capybara.default_driver).to eq(:culerity) end end describe '#current_driver' do it "should default to the default driver" do expect(Capybara.current_driver).to eq(:rack_test) Capybara.default_driver = :culerity expect(Capybara.current_driver).to eq(:culerity) end it "should be changeable" do Capybara.current_driver = :culerity expect(Capybara.current_driver).to eq(:culerity) end end describe '#javascript_driver' do it "should default to selenium" do expect(Capybara.javascript_driver).to eq(:selenium) end it "should be changeable" do Capybara.javascript_driver = :culerity expect(Capybara.javascript_driver).to eq(:culerity) end end describe '#use_default_driver' do it "should restore the default driver" do Capybara.current_driver = :culerity Capybara.use_default_driver expect(Capybara.current_driver).to eq(:rack_test) end end describe '#using_driver' do before do expect(Capybara.current_driver).not_to eq(:selenium) end it 'should set the driver using Capybara.current_driver=' do driver = nil Capybara.using_driver(:selenium) { driver = Capybara.current_driver } expect(driver).to eq(:selenium) end it 'should return the driver to default if it has not been changed' do Capybara.using_driver(:selenium) do expect(Capybara.current_driver).to eq(:selenium) end expect(Capybara.current_driver).to eq(Capybara.default_driver) end it 'should reset the driver even if an exception occurs' do driver_before_block = Capybara.current_driver begin Capybara.using_driver(:selenium) { raise "ohnoes!" } rescue Exception end expect(Capybara.current_driver).to eq(driver_before_block) end it 'should return the driver to what it was previously' do Capybara.current_driver = :selenium Capybara.using_driver(:culerity) do Capybara.using_driver(:rack_test) do expect(Capybara.current_driver).to eq(:rack_test) end expect(Capybara.current_driver).to eq(:culerity) end expect(Capybara.current_driver).to eq(:selenium) end it 'should yield the passed block' do called = false Capybara.using_driver(:selenium) { called = true } expect(called).to eq(true) end end describe '#using_wait_time' do before do @previous_wait_time = Capybara.default_max_wait_time end after do Capybara.default_max_wait_time = @previous_wait_time end it "should switch the wait time and switch it back" do in_block = nil Capybara.using_wait_time 6 do in_block = Capybara.default_max_wait_time end expect(in_block).to eq(6) expect(Capybara.default_max_wait_time).to eq(@previous_wait_time) end it "should ensure wait time is reset" do expect do Capybara.using_wait_time 6 do raise "hell" end end.to raise_error(RuntimeError, "hell") expect(Capybara.default_max_wait_time).to eq(@previous_wait_time) end end describe '#app' do it "should be changeable" do Capybara.app = "foobar" expect(Capybara.app).to eq('foobar') end end describe '#current_session' do it "should choose a session object of the current driver type" do expect(Capybara.current_session).to be_a(Capybara::Session) end it "should use #app as the application" do Capybara.app = proc {} expect(Capybara.current_session.app).to eq(Capybara.app) end it "should change with the current driver" do expect(Capybara.current_session.mode).to eq(:rack_test) Capybara.current_driver = :selenium expect(Capybara.current_session.mode).to eq(:selenium) end it "should be persistent even across driver changes" do object_id = Capybara.current_session.object_id expect(Capybara.current_session.object_id).to eq(object_id) Capybara.current_driver = :selenium expect(Capybara.current_session.mode).to eq(:selenium) expect(Capybara.current_session.object_id).not_to eq(object_id) Capybara.current_driver = :rack_test expect(Capybara.current_session.object_id).to eq(object_id) end it "should change when changing application" do object_id = Capybara.current_session.object_id expect(Capybara.current_session.object_id).to eq(object_id) Capybara.app = proc {} expect(Capybara.current_session.object_id).not_to eq(object_id) expect(Capybara.current_session.app).to eq(Capybara.app) end it "should change when the session name changes" do object_id = Capybara.current_session.object_id Capybara.session_name = :administrator expect(Capybara.session_name).to eq(:administrator) expect(Capybara.current_session.object_id).not_to eq(object_id) Capybara.session_name = :default expect(Capybara.session_name).to eq(:default) expect(Capybara.current_session.object_id).to eq(object_id) end end describe "#using_session" do it "should change the session name for the duration of the block" do expect(Capybara.session_name).to eq(:default) Capybara.using_session(:administrator) do expect(Capybara.session_name).to eq(:administrator) end expect(Capybara.session_name).to eq(:default) end it "should reset the session to the default, even if an exception occurs" do begin Capybara.using_session(:raise) do raise end rescue Exception end expect(Capybara.session_name).to eq(:default) end it "should yield the passed block" do called = false Capybara.using_session(:administrator) { called = true } expect(called).to eq(true) end it "should be nestable" do Capybara.using_session(:outer) do expect(Capybara.session_name).to eq(:outer) Capybara.using_session(:inner) do expect(Capybara.session_name).to eq(:inner) end expect(Capybara.session_name).to eq(:outer) end expect(Capybara.session_name).to eq(:default) end end describe "#session_name" do it "should default to :default" do expect(Capybara.session_name).to eq(:default) end end describe 'the DSL' do before do @session = Class.new { include Capybara::DSL }.new end it "should be possible to include it in another class" do @session.visit('/with_html') @session.click_link('ullamco') expect(@session.body).to include('Another World') end it "should provide a 'page' shortcut for more expressive tests" do @session.page.visit('/with_html') @session.page.click_link('ullamco') expect(@session.page.body).to include('Another World') end it "should provide an 'using_session' shortcut" do expect(Capybara).to receive(:using_session).with(:name) @session.using_session(:name) end it "should provide a 'using_wait_time' shortcut" do expect(Capybara).to receive(:using_wait_time).with(6) @session.using_wait_time(6) end end end capybara-2.5.0/spec/fixtures/0000755000175000017500000000000012573712570015140 5ustar lunarlunarcapybara-2.5.0/spec/fixtures/selenium_driver_rspec_success.rb0000644000175000017500000000032712573712570023607 0ustar lunarlunarrequire 'spec_helper' RSpec.describe Capybara::Selenium::Driver do it "should exit with a zero exit status" do browser = Capybara::Selenium::Driver.new(TestApp).browser expect(true).to eq(true) end end capybara-2.5.0/spec/fixtures/selenium_driver_rspec_failure.rb0000644000175000017500000000033412573712570023564 0ustar lunarlunarrequire 'spec_helper' RSpec.describe Capybara::Selenium::Driver do it "should exit with a non-zero exit status" do browser = Capybara::Selenium::Driver.new(TestApp).browser expect(true).to eq(false) end end capybara-2.5.0/spec/rspec/0000755000175000017500000000000012573712570014403 5ustar lunarlunarcapybara-2.5.0/spec/rspec/views_spec.rb0000644000175000017500000000031412573712570017075 0ustar lunarlunarrequire 'spec_helper' RSpec.describe "capybara/rspec", type: :view do it "allows matchers to be used on strings" do expect(%{

Test header

}).to have_css("h1", text: "Test header") end end capybara-2.5.0/spec/rspec/matchers_spec.rb0000644000175000017500000006644312573712570017565 0ustar lunarlunarrequire 'spec_helper' require 'capybara/dsl' require 'capybara/rspec/matchers' RSpec.describe Capybara::RSpecMatchers do include Capybara::DSL include Capybara::RSpecMatchers describe "have_css matcher" do it "gives proper description" do expect(have_css('h1').description).to eq("have css \"h1\"") end context "on a string" do context "with should" do it "passes if has_css? returns true" do expect("

Text

").to have_css('h1') end it "fails if has_css? returns false" do expect do expect("

Text

").to have_css('h2') end.to raise_error(/expected to find css "h2" but there were no matches/) end it "passes if matched node count equals expected count" do expect("

Text

").to have_css('h1', :count => 1) end it "fails if matched node count does not equal expected count" do expect do expect("

Text

").to have_css('h1', count: 2) end.to raise_error("expected to find css \"h1\" 2 times, found 1 match: \"Text\"") end it "fails if matched node count is less than expected minimum count" do expect do expect("

Text

").to have_css('p', minimum: 1) end.to raise_error("expected to find css \"p\" at least 1 time but there were no matches") end it "fails if matched node count is more than expected maximum count" do expect do expect("

Text

Text

Text

").to have_css('h1', maximum: 2) end.to raise_error('expected to find css "h1" at most 2 times, found 3 matches: "Text", "Text", "Text"') end it "fails if matched node count does not belong to expected range" do expect do expect("

Text

").to have_css('h1', between: 2..3) end.to raise_error("expected to find css \"h1\" between 2 and 3 times, found 1 match: \"Text\"") end end context "with should_not" do it "passes if has_no_css? returns true" do expect("

Text

").not_to have_css('h2') end it "fails if has_no_css? returns false" do expect do expect("

Text

").not_to have_css('h1') end.to raise_error(/expected not to find css "h1"/) end it "passes if matched node count does not equal expected count" do expect("

Text

").not_to have_css('h1', :count => 2) end it "fails if matched node count equals expected count" do expect do expect("

Text

").not_to have_css('h1', :count => 1) end.to raise_error(/expected not to find css "h1"/) end end it "supports compounding" do expect("

Text

Text

").to have_css('h1').and have_css('h2') expect("

Text

Text

").to have_css('h3').or have_css('h1') end if RSpec::Version::STRING.to_f >= 3.0 end context "on a page or node" do before do visit('/with_html') end context "with should" do it "passes if has_css? returns true" do expect(page).to have_css('h1') end it "fails if has_css? returns false" do expect do expect(page).to have_css('h1#doesnotexist') end.to raise_error(/expected to find css "h1#doesnotexist" but there were no matches/) end end context "with should_not" do it "passes if has_no_css? returns true" do expect(page).not_to have_css('h1#doesnotexist') end it "fails if has_no_css? returns false" do expect do expect(page).not_to have_css('h1') end.to raise_error(/expected not to find css "h1"/) end end end end describe "have_xpath matcher" do it "gives proper description" do expect(have_xpath('//h1').description).to eq("have xpath \"\/\/h1\"") end context "on a string" do context "with should" do it "passes if has_xpath? returns true" do expect("

Text

").to have_xpath('//h1') end it "fails if has_xpath? returns false" do expect do expect("

Text

").to have_xpath('//h2') end.to raise_error(%r(expected to find xpath "//h2" but there were no matches)) end end context "with should_not" do it "passes if has_no_xpath? returns true" do expect("

Text

").not_to have_xpath('//h2') end it "fails if has_no_xpath? returns false" do expect do expect("

Text

").not_to have_xpath('//h1') end.to raise_error(%r(expected not to find xpath "//h1")) end end it "supports compounding" do expect("

Text

Text

").to have_xpath('//h1').and have_xpath('//h2') expect("

Text

Text

").to have_xpath('//h3').or have_xpath('//h1') end if RSpec::Version::STRING.to_f >= 3.0 end context "on a page or node" do before do visit('/with_html') end context "with should" do it "passes if has_xpath? returns true" do expect(page).to have_xpath('//h1') end it "fails if has_xpath? returns false" do expect do expect(page).to have_xpath("//h1[@id='doesnotexist']") end.to raise_error(%r(expected to find xpath "//h1\[@id='doesnotexist'\]" but there were no matches)) end end context "with should_not" do it "passes if has_no_xpath? returns true" do expect(page).not_to have_xpath('//h1[@id="doesnotexist"]') end it "fails if has_no_xpath? returns false" do expect do expect(page).not_to have_xpath('//h1') end.to raise_error(%r(expected not to find xpath "//h1")) end end end end describe "have_selector matcher" do it "gives proper description" do matcher = have_selector('//h1') expect("

Text

").to matcher expect(matcher.description).to eq("have xpath \"//h1\"") end context "on a string" do context "with should" do it "passes if has_selector? returns true" do expect("

Text

").to have_selector('//h1') end it "fails if has_selector? returns false" do expect do expect("

Text

").to have_selector('//h2') end.to raise_error(%r(expected to find xpath "//h2" but there were no matches)) end end context "with should_not" do it "passes if has_no_selector? returns true" do expect("

Text

").not_to have_selector(:css, 'h2') end it "fails if has_no_selector? returns false" do expect do expect("

Text

").not_to have_selector(:css, 'h1') end.to raise_error(%r(expected not to find css "h1")) end end end context "on a page or node" do before do visit('/with_html') end context "with should" do it "passes if has_selector? returns true" do expect(page).to have_selector('//h1', :text => 'test') end it "fails if has_selector? returns false" do expect do expect(page).to have_selector("//h1[@id='doesnotexist']") end.to raise_error(%r(expected to find xpath "//h1\[@id='doesnotexist'\]" but there were no matches)) end it "includes text in error message" do expect do expect(page).to have_selector("//h1", :text => 'wrong text') end.to raise_error(%r(expected to find xpath "//h1" with text "wrong text" but there were no matches)) end end context "with should_not" do it "passes if has_no_css? returns true" do expect(page).not_to have_selector(:css, 'h1#doesnotexist') end it "fails if has_no_selector? returns false" do expect do expect(page).not_to have_selector(:css, 'h1', :text => 'test') end.to raise_error(%r(expected not to find css "h1" with text "test")) end end end it "supports compounding" do expect("

Text

Text

").to have_selector('//h1').and have_selector('//h2') expect("

Text

Text

").to have_selector('//h3').or have_selector('//h1') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_content matcher" do it "gives proper description" do expect(have_content('Text').description).to eq("text \"Text\"") end context "on a string" do context "with should" do it "passes if has_content? returns true" do expect("

Text

").to have_content('Text') end it "passes if has_content? returns true using regexp" do expect("

Text

").to have_content(/ext/) end it "fails if has_content? returns false" do expect do expect("

Text

").to have_content('No such Text') end.to raise_error(/expected to find text "No such Text" in "Text"/) end end context "with should_not" do it "passes if has_no_content? returns true" do expect("

Text

").not_to have_content('No such Text') end it "passes because escapes any characters that would have special meaning in a regexp" do expect("

Text

").not_to have_content('.') end it "fails if has_no_content? returns false" do expect do expect("

Text

").not_to have_content('Text') end.to raise_error(/expected not to find text "Text" in "Text"/) end end end context "on a page or node" do before do visit('/with_html') end context "with should" do it "passes if has_content? returns true" do expect(page).to have_content('This is a test') end it "passes if has_content? returns true using regexp" do expect(page).to have_content(/test/) end it "fails if has_content? returns false" do expect do expect(page).to have_content('No such Text') end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/) end context "with default selector CSS" do before { Capybara.default_selector = :css } it "fails if has_content? returns false" do expect do expect(page).to have_content('No such Text') end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/) end after { Capybara.default_selector = :xpath } end end context "with should_not" do it "passes if has_no_content? returns true" do expect(page).not_to have_content('No such Text') end it "fails if has_no_content? returns false" do expect do expect(page).not_to have_content('This is a test') end.to raise_error(/expected not to find text "This is a test"/) end end end it "supports compounding" do expect("

Text

And

").to have_content('Text').and have_content('And') expect("

Text

Or

").to have_content('XYZ').or have_content('Or') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_text matcher" do it "gives proper description" do expect(have_text('Text').description).to eq("text \"Text\"") end context "on a string" do context "with should" do it "passes if text contains given string" do expect("

Text

").to have_text('Text') end it "passes if text matches given regexp" do expect("

Text

").to have_text(/ext/) end it "fails if text doesn't contain given string" do expect do expect("

Text

").to have_text('No such Text') end.to raise_error(/expected to find text "No such Text" in "Text"/) end it "fails if text doesn't match given regexp" do expect do expect("

Text

").to have_text(/No such Text/) end.to raise_error('expected to find text matching /No such Text/ in "Text"') end it "casts Fixnum to string" do expect do expect("

Text

").to have_text(3) end.to raise_error(/expected to find text "3" in "Text"/) end it "fails if matched text count does not equal to expected count" do expect do expect("

Text

").to have_text('Text', count: 2) end.to raise_error('expected to find text "Text" 2 times but found 1 time in "Text"') end it "fails if matched text count is less than expected minimum count" do expect do expect("

Text

").to have_text('Lorem', minimum: 1) end.to raise_error('expected to find text "Lorem" at least 1 time but found 0 times in "Text"') end it "fails if matched text count is more than expected maximum count" do expect do expect("

Text TextText

").to have_text('Text', maximum: 2) end.to raise_error('expected to find text "Text" at most 2 times but found 3 times in "Text TextText"') end it "fails if matched text count does not belong to expected range" do expect do expect("

Text

").to have_text('Text', between: 2..3) end.to raise_error('expected to find text "Text" between 2 and 3 times but found 1 time in "Text"') end end context "with should_not" do it "passes if text doesn't contain a string" do expect("

Text

").not_to have_text('No such Text') end it "passes because escapes any characters that would have special meaning in a regexp" do expect("

Text

").not_to have_text('.') end it "fails if text contains a string" do expect do expect("

Text

").not_to have_text('Text') end.to raise_error(/expected not to find text "Text" in "Text"/) end end end context "on a page or node" do before do visit('/with_html') end context "with should" do it "passes if has_text? returns true" do expect(page).to have_text('This is a test') end it "passes if has_text? returns true using regexp" do expect(page).to have_text(/test/) end it "can check for all text" do expect(page).to have_text(:all, 'Some of this text is hidden!') end it "can check for visible text" do expect(page).to have_text(:visible, 'Some of this text is') expect(page).not_to have_text(:visible, 'Some of this text is hidden!') end it "fails if has_text? returns false" do expect do expect(page).to have_text('No such Text') end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/) end context "with default selector CSS" do before { Capybara.default_selector = :css } it "fails if has_text? returns false" do expect do expect(page).to have_text('No such Text') end.to raise_error(/expected to find text "No such Text" in "(.*)This is a test(.*)"/) end after { Capybara.default_selector = :xpath } end end context "with should_not" do it "passes if has_no_text? returns true" do expect(page).not_to have_text('No such Text') end it "fails if has_no_text? returns false" do expect do expect(page).not_to have_text('This is a test') end.to raise_error(/expected not to find text "This is a test"/) end end end it "supports compounding" do expect("

Text

And

").to have_text('Text').and have_text('And') expect("

Text

Or

").to have_text('Not here').or have_text('Or') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_link matcher" do let(:html) { 'Just a linkAnother link' } it "gives proper description" do expect(have_link('Just a link').description).to eq("have link \"Just a link\"") end it "passes if there is such a button" do expect(html).to have_link('Just a link') end it "fails if there is no such button" do expect do expect(html).to have_link('No such Link') end.to raise_error(/expected to find link "No such Link"/) end it "supports compounding" do expect(html).to have_link('Just a link').and have_link('Another link') expect(html).to have_link('Not a link').or have_link('Another link') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_title matcher" do it "gives proper description" do expect(have_title('Just a title').description).to eq("have title \"Just a title\"") end context "on a string" do let(:html) { 'Just a title' } it "passes if there is such a title" do expect(html).to have_title('Just a title') end it "fails if there is no such title" do expect do expect(html).to have_title('No such title') end.to raise_error('expected "Just a title" to include "No such title"') end it "fails if title doesn't match regexp" do expect do expect(html).to have_title(/[[:upper:]]+[[:lower:]]+l{2}o/) end.to raise_error('expected "Just a title" to match /[[:upper:]]+[[:lower:]]+l{2}o/') end end context "on a page or node" do it "passes if there is such a title" do visit('/with_js') expect(page).to have_title('with_js') end it "fails if there is no such title" do visit('/with_js') expect do expect(page).to have_title('No such title') end.to raise_error('expected "with_js" to include "No such title"') end context 'with wait' do before(:each) do @session = TestSessions::Selenium @session.visit('/with_js') end it 'waits if wait time is more than timeout' do @session.click_link("Change title") using_wait_time 0 do expect(@session).to have_title('changed title', wait: 0.5) end end it "doesn't wait if wait time is less than timeout" do @session.click_link("Change title") using_wait_time 0 do expect(@session).not_to have_title('changed title') end end end end it "supports compounding" do expect("I compound").to have_title('I dont compound').or have_title('I compound') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_current_path matcher" do it "gives proper description" do expect(have_current_path('http://www.example.com').description).to eq("have current path \"http://www.example.com\"") end context "on a page or node" do it "passes if there is such a current path" do visit('/with_js') expect(page).to have_current_path('/with_js') end it "fails if there is no such current_path" do visit('/with_js') expect do expect(page).to have_current_path('/not_with_js') end.to raise_error('expected "/with_js" to equal "/not_with_js"') end context 'with wait' do before(:each) do @session = TestSessions::Selenium @session.visit('/with_js') end it 'waits if wait time is more than timeout' do @session.click_link("Change page") using_wait_time 0 do expect(@session).to have_current_path('/with_html', wait: 1) end end it "doesn't wait if wait time is less than timeout" do @session.click_link("Change page") using_wait_time 0 do expect(@session).not_to have_current_path('/with_html') end end end end it "supports compounding" do visit('/with_html') expect(page).to have_current_path('/not_with_html').or have_current_path('/with_html') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_button matcher" do let(:html) { '' } it "gives proper description" do expect(have_button('A button').description).to eq("have button \"A button\"") end it "passes if there is such a button" do expect(html).to have_button('A button') end it "fails if there is no such button" do expect do expect(html).to have_button('No such Button') end.to raise_error(/expected to find button "No such Button"/) end it "supports compounding" do expect(html).to have_button('Not this button').or have_button('A button') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_field matcher" do let(:html) { '

' } it "gives proper description" do expect(have_field('Text field').description).to eq("have field \"Text field\"") end it "gives proper description for a given value" do expect(have_field('Text field', with: 'some value').description).to eq("have field \"Text field\" with value \"some value\"") end it "passes if there is such a field" do expect(html).to have_field('Text field') end it "passes if there is such a field with value" do expect(html).to have_field('Text field', with: 'some value') end it "fails if there is no such field" do expect do expect(html).to have_field('No such Field') end.to raise_error(/expected to find field "No such Field"/) end it "fails if there is such field but with false value" do expect do expect(html).to have_field('Text field', with: 'false value') end.to raise_error(/expected to find field "Text field"/) end it "treats a given value as a string" do class Foo def to_s "some value" end end expect(html).to have_field('Text field', with: Foo.new) end it "supports compounding" do expect(html).to have_field('Not this one').or have_field('Text field') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_checked_field matcher" do let(:html) do ' ' end it "gives proper description" do expect(have_checked_field('it is checked').description).to eq("have field \"it is checked\" that is checked") end context "with should" do it "passes if there is such a field and it is checked" do expect(html).to have_checked_field('it is checked') end it "fails if there is such a field but it is not checked" do expect do expect(html).to have_checked_field('unchecked field') end.to raise_error(/expected to find field "unchecked field"/) end it "fails if there is no such field" do expect do expect(html).to have_checked_field('no such field') end.to raise_error(/expected to find field "no such field"/) end end context "with should not" do it "fails if there is such a field and it is checked" do expect do expect(html).not_to have_checked_field('it is checked') end.to raise_error(/expected not to find field "it is checked"/) end it "passes if there is such a field but it is not checked" do expect(html).not_to have_checked_field('unchecked field') end it "passes if there is no such field" do expect(html).not_to have_checked_field('no such field') end end it "supports compounding" do expect(html).to have_checked_field('not this one').or have_checked_field('it is checked') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_unchecked_field matcher" do let(:html) do ' ' end it "gives proper description" do expect(have_unchecked_field('unchecked field').description).to eq("have field \"unchecked field\" that is not checked") end context "with should" do it "passes if there is such a field and it is not checked" do expect(html).to have_unchecked_field('unchecked field') end it "fails if there is such a field but it is checked" do expect do expect(html).to have_unchecked_field('it is checked') end.to raise_error(/expected to find field "it is checked"/) end it "fails if there is no such field" do expect do expect(html).to have_unchecked_field('no such field') end.to raise_error(/expected to find field "no such field"/) end end context "with should not" do it "fails if there is such a field and it is not checked" do expect do expect(html).not_to have_unchecked_field('unchecked field') end.to raise_error(/expected not to find field "unchecked field"/) end it "passes if there is such a field but it is checked" do expect(html).not_to have_unchecked_field('it is checked') end it "passes if there is no such field" do expect(html).not_to have_unchecked_field('no such field') end end it "supports compounding" do expect(html).to have_unchecked_field('it is checked').or have_unchecked_field('unchecked field') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_select matcher" do let(:html) { '' } it "gives proper description" do expect(have_select('Select Box').description).to eq("have select box \"Select Box\"") end it "gives proper description for a given selected value" do expect(have_select('Select Box', selected: 'some value').description).to eq("have select box \"Select Box\" with \"some value\" selected") end it "passes if there is such a select" do expect(html).to have_select('Select Box') end it "fails if there is no such select" do expect do expect(html).to have_select('No such Select box') end.to raise_error(/expected to find select box "No such Select box"/) end it "supports compounding" do expect(html).to have_select('Not this one').or have_select('Select Box') end if RSpec::Version::STRING.to_f >= 3.0 end describe "have_table matcher" do let(:html) { '
Lovely table
' } it "gives proper description" do expect(have_table('Lovely table').description).to eq("have table \"Lovely table\"") end it "passes if there is such a select" do expect(html).to have_table('Lovely table') end it "fails if there is no such select" do expect do expect(html).to have_table('No such Table') end.to raise_error(/expected to find table "No such Table"/) end it "supports compounding" do expect(html).to have_table('nope').or have_table('Lovely table') end if RSpec::Version::STRING.to_f >= 3.0 end end capybara-2.5.0/spec/rspec/features_spec.rb0000644000175000017500000000414412573712570017563 0ustar lunarlunarrequire 'spec_helper' require 'capybara/rspec' RSpec.configuration.before(:each, { file_path: "./spec/rspec/features_spec.rb" } ) do @in_filtered_hook = true end feature "Capybara's feature DSL" do background do @in_background = true end def current_example(context) RSpec.respond_to?(:current_example) ? RSpec.current_example : context.example end scenario "includes Capybara" do visit('/') expect(page).to have_content('Hello world!') end scenario "preserves description" do expect(current_example(self).metadata[:full_description]) .to eq("Capybara's feature DSL preserves description") end scenario "allows driver switching", :driver => :selenium do expect(Capybara.current_driver).to eq(:selenium) end scenario "runs background" do expect(@in_background).to be_truthy end scenario "runs hooks filtered by file path" do expect(@in_filtered_hook).to be_truthy end scenario "doesn't pollute the Object namespace" do expect(Object.new.respond_to?(:feature, true)).to be_falsey end feature 'nested features' do scenario 'work as expected' do visit '/' expect(page).to have_content 'Hello world!' end scenario 'are marked in the metadata as capybara_feature' do expect(current_example(self).metadata[:capybara_feature]).to be_truthy end scenario 'have a type of :feature' do expect(current_example(self).metadata[:type]).to eq :feature end end end feature "given and given! aliases to let and let!" do given(:value) { :available } given!(:value_in_background) { :available } background do expect(value_in_background).to be(:available) end scenario "given and given! work as intended" do expect(value).to be(:available) expect(value_in_background).to be(:available) end end feature "if xscenario aliases to pending then" do xscenario "this test should be 'temporarily disabled with xscenario'" do end end feature "Capybara's feature DSL with driver", :driver => :culerity do scenario "switches driver" do expect(Capybara.current_driver).to eq(:culerity) end end capybara-2.5.0/lib/0000755000175000017500000000000012573712570013103 5ustar lunarlunarcapybara-2.5.0/lib/capybara.rb0000644000175000017500000003151512573712570015217 0ustar lunarlunarrequire 'timeout' require 'nokogiri' require 'xpath' module Capybara class CapybaraError < StandardError; end class DriverNotFoundError < CapybaraError; end class FrozenInTime < CapybaraError; end class ElementNotFound < CapybaraError; end class ModalNotFound < CapybaraError; end class Ambiguous < ElementNotFound; end class ExpectationNotMet < ElementNotFound; end class FileNotFound < CapybaraError; end class UnselectNotAllowed < CapybaraError; end class NotSupportedByDriverError < CapybaraError; end class InfiniteRedirectError < CapybaraError; end class ScopeError < CapybaraError; end class WindowError < CapybaraError; end class ReadOnlyElementError < CapybaraError; end class << self attr_accessor :asset_host, :app_host, :run_server, :default_host, :always_include_port attr_accessor :server_port, :exact, :match, :exact_options, :visible_text_only attr_accessor :default_selector, :default_max_wait_time, :ignore_hidden_elements attr_accessor :save_and_open_page_path, :wait_on_first_by_default, :automatic_reload, :raise_server_errors, :server_errors attr_writer :default_driver, :current_driver, :javascript_driver, :session_name, :server_host attr_accessor :app ## # # Configure Capybara to suit your needs. # # Capybara.configure do |config| # config.run_server = false # config.app_host = 'http://www.google.com' # end # # === Configurable options # # [app_host = String] The default host to use when giving a relative URL to visit # [always_include_port = Boolean] Whether the Rack server's port should automatically be inserted into every visited URL (Default: false) # [asset_host = String] Where dynamic assets are hosted - will be prepended to relative asset locations if present (Default: nil) # [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true) # [raise_server_errors = Boolean] Should errors raised in the server be raised in the tests? (Default: true) # [server_errors = Array\] Error classes that should be raised in the tests if they are raised in the server and Capybara.raise_server_errors is true (Default: [StandardError]) # [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: :css) # [default_max_wait_time = Numeric] The maximum number of seconds to wait for asynchronous processes to finish (Default: 2) # [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true) # [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true) # [save_and_open_page_path = String] Where to put pages saved through save_and_open_page (Default: Dir.pwd) # [wait_on_first_by_default = Boolean] Whether Node#first defaults to Capybara waiting behavior for at least 1 element to match (Default: false) # === DSL Options # # when using capybara/dsl, the following options are also available: # # [default_driver = Symbol] The name of the driver to use by default. (Default: :rack_test) # [javascript_driver = Symbol] The name of a driver to use for JavaScript enabled tests. (Default: :selenium) # def configure yield self end ## # # Register a new driver for Capybara. # # Capybara.register_driver :rack_test do |app| # Capybara::RackTest::Driver.new(app) # end # # @param [Symbol] name The name of the new driver # @yield [app] This block takes a rack app and returns a Capybara driver # @yieldparam [] app The rack application that this driver runs against. May be nil. # @yieldreturn [Capybara::Driver::Base] A Capybara driver instance # def register_driver(name, &block) drivers[name] = block end ## # # Add a new selector to Capybara. Selectors can be used by various methods in Capybara # to find certain elements on the page in a more convenient way. For example adding a # selector to find certain table rows might look like this: # # Capybara.add_selector(:row) do # xpath { |num| ".//tbody/tr[#{num}]" } # end # # This makes it possible to use this selector in a variety of ways: # # find(:row, 3) # page.find('table#myTable').find(:row, 3).text # page.find('table#myTable').has_selector?(:row, 3) # within(:row, 3) { expect(page).to have_content('$100.000') } # # Here is another example: # # Capybara.add_selector(:id) do # xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] } # end # # Note that this particular selector already ships with Capybara. # # @param [Symbol] name The name of the selector to add # @yield A block executed in the context of the new {Capybara::Selector} # def add_selector(name, &block) Capybara::Selector.add(name, &block) end def drivers @drivers ||= {} end ## # # Register a proc that Capybara will call to run the Rack application. # # Capybara.server do |app, port| # require 'rack/handler/mongrel' # Rack::Handler::Mongrel.run(app, :Port => port) # end # # By default, Capybara will try to run webrick. # # @yield [app, port] This block receives a rack app and port and should run a Rack handler # def server(&block) if block_given? @server = block else @server end end ## # # Wraps the given string, which should contain an HTML document or fragment # in a {Capybara::Node::Simple} which exposes all {Capybara::Node::Matchers}, # {Capybara::Node::Finders} and {Capybara::Node::DocumentMatchers}. This allows you to query # any string containing HTML in the exact same way you would query the current document in a Capybara # session. For example: # # node = Capybara.string <<-HTML # # HTML # # node.find('#projects').text # => 'Projects' # node.has_selector?('li#home', :text => 'Home') # node.has_selector?('#projects') # node.find('ul').find('li:first-child').text # => 'Home' # # @param [String] html An html fragment or document # @return [Capybara::Node::Simple] A node which has Capybara's finders and matchers # def string(html) Capybara::Node::Simple.new(html) end ## # # Runs Capybara's default server for the given application and port # under most circumstances you should not have to call this method # manually. # # @param [Rack Application] app The rack application to run # @param [Fixnum] port The port to run the application on # def run_default_server(app, port) require 'rack/handler/webrick' Rack::Handler::WEBrick.run(app, :Host => server_host, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0)) end ## # # @return [Symbol] The name of the driver to use by default # def default_driver @default_driver || :rack_test end ## # # @return [Symbol] The name of the driver currently in use # def current_driver @current_driver || default_driver end alias_method :mode, :current_driver ## # # @return [Symbol] The name of the driver used when JavaScript is needed # def javascript_driver @javascript_driver || :selenium end ## # # Use the default driver as the current driver # def use_default_driver @current_driver = nil end ## # # Yield a block using a specific driver # def using_driver(driver) previous_driver = Capybara.current_driver Capybara.current_driver = driver yield ensure @current_driver = previous_driver end ## # # @return [String] The IP address bound by default server # def server_host @server_host || '127.0.0.1' end ## # # Yield a block using a specific wait time # def using_wait_time(seconds) previous_wait_time = Capybara.default_max_wait_time Capybara.default_max_wait_time = seconds yield ensure Capybara.default_max_wait_time = previous_wait_time end ## # # The current Capybara::Session based on what is set as Capybara.app and Capybara.current_driver # # @return [Capybara::Session] The currently used session # def current_session session_pool["#{current_driver}:#{session_name}:#{app.object_id}"] ||= Capybara::Session.new(current_driver, app) end ## # # Reset sessions, cleaning out the pool of sessions. This will remove any session information such # as cookies. # def reset_sessions! session_pool.each { |mode, session| session.reset! } end alias_method :reset!, :reset_sessions! ## # # The current session name. # # @return [Symbol] The name of the currently used session. # def session_name @session_name ||= :default end ## # # Yield a block using a specific session name. # def using_session(name) previous_session_name = self.session_name self.session_name = name yield ensure self.session_name = previous_session_name end ## # # Parse raw html into a document using Nokogiri, and adjust textarea contents as defined by the spec. # # @param [String] html The raw html # @return [Nokogiri::HTML::Document] HTML document # def HTML(html) Nokogiri::HTML(html).tap do |document| document.xpath('//textarea').each do |textarea| textarea.content=textarea.content.sub(/\A\n/,'') end end end # @deprecated Use default_max_wait_time instead def default_wait_time deprecate('default_wait_time', 'default_max_wait_time', true) default_max_wait_time end # @deprecated Use default_max_wait_time= instead def default_wait_time=(t) deprecate('default_wait_time=', 'default_max_wait_time=') self.default_max_wait_time = t end def included(base) base.send(:include, Capybara::DSL) warn "`include Capybara` is deprecated. Please use `include Capybara::DSL` instead." end def deprecate(method, alternate_method, once=false) @deprecation_notified ||= {} warn "DEPRECATED: ##{method} is deprecated, please use ##{alternate_method} instead" unless once and @deprecation_notified[method] @deprecation_notified[method]=true end private def session_pool @session_pool ||= {} end end self.default_driver = nil self.current_driver = nil self.server_host = nil module Driver; end module RackTest; end module Selenium; end require 'capybara/helpers' require 'capybara/session' require 'capybara/dsl' require 'capybara/window' require 'capybara/server' require 'capybara/selector' require 'capybara/result' require 'capybara/version' require 'capybara/queries/base_query' require 'capybara/query' require 'capybara/queries/text_query' require 'capybara/queries/title_query' require 'capybara/queries/current_path_query' require 'capybara/node/finders' require 'capybara/node/matchers' require 'capybara/node/actions' require 'capybara/node/document_matchers' require 'capybara/node/simple' require 'capybara/node/base' require 'capybara/node/element' require 'capybara/node/document' require 'capybara/driver/base' require 'capybara/driver/node' require 'capybara/rack_test/driver' require 'capybara/rack_test/node' require 'capybara/rack_test/form' require 'capybara/rack_test/browser' require 'capybara/rack_test/css_handlers.rb' require 'capybara/selenium/node' require 'capybara/selenium/driver' end Capybara.configure do |config| config.always_include_port = false config.run_server = true config.server {|app, port| Capybara.run_default_server(app, port)} config.default_selector = :css config.default_max_wait_time = 2 config.ignore_hidden_elements = true config.default_host = "http://www.example.com" config.automatic_reload = true config.match = :smart config.exact = false config.raise_server_errors = true config.server_errors = [StandardError] config.visible_text_only = false config.wait_on_first_by_default = false end Capybara.register_driver :rack_test do |app| Capybara::RackTest::Driver.new(app) end Capybara.register_driver :selenium do |app| Capybara::Selenium::Driver.new(app) end capybara-2.5.0/lib/capybara/0000755000175000017500000000000012573712570014665 5ustar lunarlunarcapybara-2.5.0/lib/capybara/server.rb0000644000175000017500000000361512573712570016525 0ustar lunarlunarrequire 'uri' require 'net/http' require 'rack' module Capybara class Server class Middleware attr_accessor :error def initialize(app) @app = app end def call(env) if env["PATH_INFO"] == "/__identify__" [200, {}, [@app.object_id.to_s]] else begin @app.call(env) rescue *Capybara.server_errors => e @error = e unless @error raise e end end end end class << self def ports @ports ||= {} end end attr_reader :app, :port, :host def initialize(app, port=Capybara.server_port, host=Capybara.server_host) @app = app @middleware = Middleware.new(@app) @server_thread = nil # suppress warnings @host, @port = host, port @port ||= Capybara::Server.ports[@app.object_id] @port ||= find_available_port end def reset_error! @middleware.error = nil end def error @middleware.error end def responsive? return false if @server_thread && @server_thread.join(0) res = Net::HTTP.start(host, @port) { |http| http.get('/__identify__') } if res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection) return res.body == @app.object_id.to_s end rescue SystemCallError return false end def boot unless responsive? Capybara::Server.ports[@app.object_id] = @port @server_thread = Thread.new do Capybara.server.call(@middleware, @port) end Timeout.timeout(60) { @server_thread.join(0.1) until responsive? } end rescue Timeout::Error raise "Rack application timed out during boot" else self end private def find_available_port server = TCPServer.new('127.0.0.1', 0) server.addr[1] ensure server.close if server end end end capybara-2.5.0/lib/capybara/query.rb0000644000175000017500000000725412573712570016367 0ustar lunarlunarmodule Capybara # @deprecated This class and its methods are not supposed to be used by users of Capybara's public API. # It may be removed in future versions of Capybara. class Query < Queries::BaseQuery attr_accessor :selector, :locator, :options, :expression, :find, :negative VALID_KEYS = [:text, :visible, :between, :count, :maximum, :minimum, :exact, :match, :wait] VALID_MATCH = [:first, :smart, :prefer_exact, :one] def initialize(*args) @options = if args.last.is_a?(Hash) then args.pop.dup else {} end if args[0].is_a?(Symbol) @selector = Selector.all[args[0]] @locator = args[1] else @selector = Selector.all.values.find { |s| s.match?(args[0]) } @locator = args[0] end @selector ||= Selector.all[Capybara.default_selector] # for compatibility with Capybara 2.0 if Capybara.exact_options and @selector == Selector.all[:option] @options[:exact] = true end @expression = @selector.call(@locator) assert_valid_keys end def name; selector.name; end def label; selector.label or selector.name; end def description @description = "#{label} #{locator.inspect}" @description << " with text #{options[:text].inspect}" if options[:text] @description << selector.description(options) @description end def matches_filters?(node) if options[:text] regexp = options[:text].is_a?(Regexp) ? options[:text] : Regexp.escape(options[:text].to_s) return false if not node.text(visible).match(regexp) end case visible when :visible then return false unless node.visible? when :hidden then return false if node.visible? end selector.custom_filters.each do |name, filter| if options.has_key?(name) return false unless filter.matches?(node, options[name]) elsif filter.default? return false unless filter.matches?(node, filter.default) end end end def visible if options.has_key?(:visible) case @options[:visible] when true then :visible when false then :all else @options[:visible] end else if Capybara.ignore_hidden_elements :visible else :all end end end def exact? if options.has_key?(:exact) @options[:exact] else Capybara.exact end end def match if options.has_key?(:match) @options[:match] else Capybara.match end end def xpath(exact=nil) exact = self.exact? if exact == nil if @expression.respond_to?(:to_xpath) and exact @expression.to_xpath(:exact) else @expression.to_s end end def css @expression end # @api private def resolve_for(node, exact = nil) node.synchronize do children = if selector.format == :css node.find_css(self.css) else node.find_xpath(self.xpath(exact)) end.map do |child| if node.is_a?(Capybara::Node::Base) Capybara::Node::Element.new(node.session, child, node, self) else Capybara::Node::Simple.new(child) end end Capybara::Result.new(children, self) end end private def valid_keys COUNT_KEYS + [:text, :visible, :exact, :match, :wait] + @selector.custom_filters.keys end def assert_valid_keys super unless VALID_MATCH.include?(match) raise ArgumentError, "invalid option #{match.inspect} for :match, should be one of #{VALID_MATCH.map(&:inspect).join(", ")}" end end end end capybara-2.5.0/lib/capybara/selector.rb0000644000175000017500000001744612573712570017046 0ustar lunarlunarmodule Capybara class Selector class Filter def initialize(name, block, options={}) @name = name @block = block @options = options @options[:valid_values] = [true,false] if options[:boolean] end def default? @options.has_key?(:default) end def default @options[:default] end def matches?(node, value) if @options.has_key?(:valid_values) && !Array(@options[:valid_values]).include?(value) warn "Invalid value #{value.inspect} passed to filter #{@name}" end @block.call(node, value) end end attr_reader :name, :custom_filters, :format class << self def all @selectors ||= {} end def add(name, &block) all[name.to_sym] = Capybara::Selector.new(name.to_sym, &block) end def remove(name) all.delete(name.to_sym) end end def initialize(name, &block) @name = name @custom_filters = {} @match = nil @label = nil @failure_message = nil @description = nil instance_eval(&block) end def xpath(&block) @format = :xpath @xpath = block if block @xpath end # Same as xpath, but wrap in XPath.css(). def css(&block) @format = :css @css = block if block @css end def match(&block) @match = block if block @match end def label(label=nil) @label = label if label @label end def description(options={}) (@description && @description.call(options)).to_s end def call(locator) if @format==:css @css.call(locator) else @xpath.call(locator) end end def match?(locator) @match and @match.call(locator) end def filter(name, options={}, &block) @custom_filters[name] = Filter.new(name, block, options) end def describe &block @description = block end end end Capybara.add_selector(:xpath) do xpath { |xpath| xpath } end Capybara.add_selector(:css) do css { |css| css } end Capybara.add_selector(:id) do xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] } end Capybara.add_selector(:field) do xpath { |locator| XPath::HTML.field(locator) } filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) } filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) } filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) } filter(:readonly, boolean: true) { |node, value| not(value ^ node[:readonly]) } filter(:with) { |node, with| node.value == with.to_s } filter(:type) do |node, type| if ['textarea', 'select'].include?(type) node.tag_name == type else node[:type] == type end end describe do |options| desc, states = "", [] desc << " of type #{options[:type].inspect}" if options[:type] desc << " with value #{options[:with].to_s.inspect}" if options.has_key?(:with) states << 'checked' if options[:checked] || (options.has_key?(:unchecked) && !options[:unchecked]) states << 'not checked' if options[:unchecked] || (options.has_key?(:checked) && !options[:checked]) states << 'disabled' if options[:disabled] desc << " that is #{states.join(' and ')}" unless states.empty? desc end end Capybara.add_selector(:fieldset) do xpath { |locator| XPath::HTML.fieldset(locator) } end Capybara.add_selector(:link_or_button) do label "link or button" xpath { |locator| XPath::HTML.link_or_button(locator) } filter(:disabled, default: false, boolean: true) { |node, value| node.tag_name == "a" or not(value ^ node.disabled?) } describe { |options| " that is disabled" if options[:disabled] } end Capybara.add_selector(:link) do xpath { |locator| XPath::HTML.link(locator) } filter(:href) do |node, href| if href.is_a? Regexp node[:href].match href else node.first(:xpath, XPath.axis(:self)[XPath.attr(:href).equals(href.to_s)], minimum: 0) end end describe { |options| " with href #{options[:href].inspect}" if options[:href] } end Capybara.add_selector(:button) do xpath { |locator| XPath::HTML.button(locator) } filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) } describe { |options| " that is disabled" if options[:disabled] } end Capybara.add_selector(:fillable_field) do label "field" xpath { |locator| XPath::HTML.fillable_field(locator) } filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) } describe { |options| " that is disabled" if options[:disabled] } end Capybara.add_selector(:radio_button) do label "radio button" xpath { |locator| XPath::HTML.radio_button(locator) } filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) } filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) } filter(:option) { |node, value| node.value == value.to_s } filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) } describe do |options| desc, states = "", [] desc << " with value #{options[:option].inspect}" if options[:option] states << 'checked' if options[:checked] || (options.has_key?(:unchecked) && !options[:unchecked]) states << 'not checked' if options[:unchecked] || (options.has_key?(:checked) && !options[:checked]) states << 'disabled' if options[:disabled] desc << " that is #{states.join(' and ')}" unless states.empty? desc end end Capybara.add_selector(:checkbox) do xpath { |locator| XPath::HTML.checkbox(locator) } filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) } filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) } filter(:option) { |node, value| node.value == value.to_s } filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) } describe do |options| desc, states = "", [] desc << " with value #{options[:option].inspect}" if options[:option] states << 'checked' if options[:checked] || (options.has_key?(:unchecked) && !options[:unchecked]) states << 'not checked' if options[:unchecked] || (options.has_key?(:checked) && !options[:checked]) states << 'disabled' if options[:disabled] desc << " that is #{states.join(' and ')}" unless states.empty? desc end end Capybara.add_selector(:select) do label "select box" xpath { |locator| XPath::HTML.select(locator) } filter(:options) do |node, options| actual = node.all(:xpath, './/option').map { |option| option.text } options.sort == actual.sort end filter(:with_options) { |node, options| options.all? { |option| node.first(:option, option, minimum: 0) } } filter(:selected) do |node, selected| actual = node.all(:xpath, './/option').select { |option| option.selected? }.map { |option| option.text } [selected].flatten.sort == actual.sort end filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) } describe do |options| desc = "" desc << " with options #{options[:options].inspect}" if options[:options] desc << " with at least options #{options[:with_options].inspect}" if options[:with_options] desc << " with #{options[:selected].inspect} selected" if options[:selected] desc << " that is disabled" if options[:disabled] desc end end Capybara.add_selector(:option) do xpath { |locator| XPath::HTML.option(locator) } end Capybara.add_selector(:file_field) do label "file field" xpath { |locator| XPath::HTML.file_field(locator) } filter(:disabled, default: false, boolean: true) { |node, value| not(value ^ node.disabled?) } describe { |options| " that is disabled" if options[:disabled] } end Capybara.add_selector(:table) do xpath { |locator| XPath::HTML.table(locator) } end capybara-2.5.0/lib/capybara/node/0000755000175000017500000000000012573712570015612 5ustar lunarlunarcapybara-2.5.0/lib/capybara/node/simple.rb0000644000175000017500000001112412573712570017427 0ustar lunarlunarmodule Capybara module Node ## # # A {Capybara::Node::Simple} is a simpler version of {Capybara::Node::Base} which # includes only {Capybara::Node::Finders} and {Capybara::Node::Matchers} and does # not include {Capybara::Node::Actions}. This type of node is returned when # using {Capybara.string}. # # It is useful in that it does not require a session, an application or a driver, # but can still use Capybara's finders and matchers on any string that contains HTML. # class Simple include Capybara::Node::Finders include Capybara::Node::Matchers include Capybara::Node::DocumentMatchers attr_reader :native def initialize(native) native = Capybara::HTML(native) if native.is_a?(String) @native = native end ## # # @return [String] The text of the element # def text(type=nil) native.text end ## # # Retrieve the given attribute # # element[:title] # => HTML title attribute # # @param [Symbol] name The attribute name to retrieve # @return [String] The value of the attribute # def [](name) attr_name = name.to_s if attr_name == 'value' value elsif 'input' == tag_name and 'checkbox' == native[:type] and 'checked' == attr_name native['checked'] == 'checked' else native[attr_name] end end ## # # @return [String] The tag name of the element # def tag_name native.node_name end ## # # An XPath expression describing where on the page the element can be found # # @return [String] An XPath expression # def path native.path end ## # # @return [String] The value of the form element # def value if tag_name == 'textarea' native.content elsif tag_name == 'select' if native['multiple'] == 'multiple' native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content } else option = native.xpath(".//option[@selected='selected']").first || native.xpath(".//option").first option[:value] || option.content if option end elsif tag_name == 'input' && %w(radio checkbox).include?(native[:type]) native[:value] || 'on' else native[:value] end end ## # # Whether or not the element is visible. Does not support CSS, so # the result may be inaccurate. # # @param [Boolean] check_ancestors Whether to inherit visibility from ancestors # @return [Boolean] Whether the element is visible # def visible?(check_ancestors = true) if check_ancestors #check size because oldest supported nokogiri doesnt support xpath boolean() function native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or @hidden or name()='script' or name()='head']").size() == 0 else #no need for an xpath if only checking the current element !(native.has_attribute?('hidden') || (native[:style] =~ /display:\s?none/) || %w(script head).include?(tag_name)) end end ## # # Whether or not the element is checked. # # @return [Boolean] Whether the element is checked # def checked? native[:checked] end ## # # Whether or not the element is disabled. # # @return [Boolean] Whether the element is disabled def disabled? native[:disabled] end ## # # Whether or not the element is selected. # # @return [Boolean] Whether the element is selected # def selected? native[:selected] end def synchronize(seconds=nil) yield # simple nodes don't need to wait end def allow_reload! # no op end def title if native.respond_to? :title native.title else #old versions of nokogiri don't have #title - remove in 3.0 native.xpath('/html/head/title | /html/title').first.text end end def inspect %(#) end # @api private def find_css(css) native.css(css) end # @api private def find_xpath(xpath) native.xpath(xpath) end end end end capybara-2.5.0/lib/capybara/node/actions.rb0000644000175000017500000001327512573712570017607 0ustar lunarlunarmodule Capybara module Node module Actions ## # # Finds a button or link by id, text or value and clicks it. Also looks at image # alt text inside the link. # # @param [String] locator Text, id or value of link or button # def click_link_or_button(locator, options={}) find(:link_or_button, locator, options).click end alias_method :click_on, :click_link_or_button ## # # Finds a link by id, text or title and clicks it. Also looks at image # alt text inside the link. # # @param [String] locator text, id, title or nested image's alt attribute # @param options See {Capybara::Node::Finders#find_link} # def click_link(locator, options={}) find(:link, locator, options).click end ## # # Finds a button on the page and clicks it. # This can be any \ element of type submit, reset, image, button or it can be a # \ capybara-2.5.0/lib/capybara/spec/views/header_links.erb0000644000175000017500000000021112573712570022070 0ustar lunarlunar

Link

capybara-2.5.0/lib/capybara/spec/views/frame_parent.erb0000644000175000017500000000025512573712570022113 0ustar lunarlunar This is the parent frame title capybara-2.5.0/lib/capybara/spec/views/with_base_tag.erb0000644000175000017500000000043512573712570022250 0ustar lunarlunar with_external_source

FooBar

This is the title of frame two
This is the text of divInFrameTwo
capybara-2.5.0/lib/capybara/spec/views/frame_child.erb0000644000175000017500000000035712573712570021710 0ustar lunarlunar This is the child frame title capybara-2.5.0/lib/capybara/spec/views/with_html.erb0000644000175000017500000000766412573712570021462 0ustar lunarlunar
<%= referrer %>

This is a test

Header Class Test One

Header Class Test Two

Header Class Test Three

Header Class Test Four

Header Class Test Five

42

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. awesome image

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat Redirect pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia text with   whitespace id est laborum.

BackToMyself A link came first A link A link with data-method A link with capitalized data-method No Href Blank Href Blank Anchor Blank JS Anchor Normal Anchor Anchor on different page Anchor on same page Relative Protocol very fine image fine image Disabled link Naked Query String <% if params[:query_string] %> Query String sent <% end %>

Some of this text is hidden!
visible link
Number 42
  • John
  • Paul
  • George
  • Ringo
singular
multiple one
multiple two
almost singular but not quite
almost singular
No href
capybara-2.5.0/lib/capybara/spec/views/postback.erb0000644000175000017500000000032412573712570021253 0ustar lunarlunar

Postback

capybara-2.5.0/lib/capybara/spec/views/buttons.erb0000644000175000017500000000022412573712570021142 0ustar lunarlunar

Buttons

capybara-2.5.0/lib/capybara/spec/views/with_simple_html.erb0000644000175000017500000000000312573712570023007 0ustar lunarlunarBarcapybara-2.5.0/lib/capybara/spec/views/popup_one.erb0000644000175000017500000000026512573712570021455 0ustar lunarlunar Title of the first popup
This is the text of divInPopupOne
capybara-2.5.0/lib/capybara/spec/views/popup_two.erb0000644000175000017500000000025712573712570021506 0ustar lunarlunar Title of popup two
This is the text of divInPopupTwo
capybara-2.5.0/lib/capybara/spec/views/fieldsets.erb0000644000175000017500000000125212573712570021430 0ustar lunarlunar
Agent

Villain

capybara-2.5.0/lib/capybara/spec/views/within_frames.erb0000644000175000017500000000052112573712570022303 0ustar lunarlunar With Frames
This is the text for divInMainWindow
capybara-2.5.0/lib/capybara/spec/views/tables.erb0000644000175000017500000000235012573712570020720 0ustar lunarlunar
Agent
Girl
Villain
capybara-2.5.0/lib/capybara/spec/views/with_count.erb0000644000175000017500000000017612573712570021635 0ustar lunarlunar

This page is used for testing number options of has_text?

count1

2 count

Count

capybara-2.5.0/lib/capybara/spec/views/with_html_entities.erb0000644000175000017500000000005412573712570023350 0ustar lunarlunarEncoding with — html entities » capybara-2.5.0/lib/capybara/spec/views/with_title.erb0000644000175000017500000000011412573712570021616 0ustar lunarlunarTest Title abcdefg capybara-2.5.0/lib/capybara/spec/views/host_links.erb0000644000175000017500000000046512573712570021630 0ustar lunarlunar

Relative Host Absolute Host

capybara-2.5.0/lib/capybara/spec/views/with_js.erb0000644000175000017500000000521612573712570021121 0ustar lunarlunar with_js

FooBar

This is text

This is a draggable element.

It should be dropped here.

Click me

Slowly

Editable content
Content

Reload! this won't change

waiting to be reloaded

Fetch new list!

  • Item 1
  • Item 2

Change title

Click me

Open alert

Open delayed alert Open slow alert

Open confirm

Open prompt

Change page

capybara-2.5.0/lib/capybara/spec/views/with_scope.erb0000644000175000017500000000250312573712570021612 0ustar lunarlunar

This page is used for testing various scopes

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia. Go

  • With Simple HTML: Go

  • Bar: Go

  • With Simple HTML: Go
capybara-2.5.0/lib/capybara/spec/views/form.erb0000644000175000017500000003457012573712570020422 0ustar lunarlunar

Form



First address

Second address

capybara-2.5.0/lib/capybara/spec/views/path.erb0000644000175000017500000000035512573712570020405 0ustar lunarlunar
First Link
Text node
Second Link Third Link
capybara-2.5.0/lib/capybara/spec/views/frame_one.erb0000644000175000017500000000027212573712570021402 0ustar lunarlunar This is the title of frame one
This is the text of divInFrameOne
capybara-2.5.0/lib/capybara/spec/views/with_hover.erb0000644000175000017500000000076312573712570021632 0ustar lunarlunar with_hover
Some text here so the wrapper has size
Here I am
capybara-2.5.0/lib/capybara/spec/test_app.rb0000644000175000017500000000704412573712570017770 0ustar lunarlunarrequire 'sinatra/base' require 'tilt/erb' require 'rack' require 'yaml' class TestApp < Sinatra::Base class TestAppError < StandardError; end set :root, File.dirname(__FILE__) set :static, true set :raise_errors, true set :show_exceptions, false # Also check lib/capybara/spec/views/*.erb for pages not listed here get '/' do response.set_cookie('capybara', { value: 'root cookie', domain: request.host, path: request.path} ) 'Hello world! Relative' end get '/foo' do 'Another World' end get '/redirect' do redirect '/redirect_again' end get '/redirect_again' do redirect '/landed' end get '/referer_base' do 'direct link' + 'link via redirect' + '
' end get '/redirect_to_get_referer' do redirect '/get_referer' end get '/get_referer' do request.referer.nil? ? "No referer" : "Got referer: #{request.referer}" end get '/host' do "Current host is #{request.scheme}://#{request.host}:#{request.port}" end get '/redirect/:times/times' do times = params[:times].to_i if times.zero? "redirection complete" else redirect "/redirect/#{times - 1}/times" end end get '/landed' do "You landed" end get '/with-quotes' do %q{"No," he said, "you can't do that."} end get '/form/get' do '
' + params[:form].to_yaml + '
' end post '/relative' do '
' + params[:form].to_yaml + '
' end get '/favicon.ico' do nil end post '/redirect' do redirect '/redirect_again' end delete "/delete" do "The requested object was deleted" end get "/delete" do "Not deleted" end get '/redirect_back' do redirect back end get '/redirect_secure' do redirect "https://#{request.host}:#{request.port}/host" end get '/slow_response' do sleep 2 'Finally!' end get '/set_cookie' do cookie_value = 'test_cookie' response.set_cookie('capybara', cookie_value) "Cookie set to #{cookie_value}" end get '/get_cookie' do request.cookies['capybara'] end get '/get_header' do env['HTTP_FOO'] end get '/get_header_via_redirect' do redirect '/get_header' end get '/error' do raise TestAppError, "some error" end get '/load_error' do raise LoadError end get '/with.*html' do erb :with_html, locals: { referrer: request.referrer } end get '/:view' do |view| erb view.to_sym, locals: { referrer: request.referrer } end post '/form' do '
' + params[:form].to_yaml + '
' end post '/upload_empty' do if params[:form][:file].nil? 'Successfully ignored empty file field.' else 'Something went wrong.' end end post '/upload' do begin buffer = [] buffer << "Content-type: #{params[:form][:document][:type]}" buffer << "File content: #{params[:form][:document][:tempfile].read}" buffer.join(' | ') rescue 'No file uploaded' end end post '/upload_multiple' do begin buffer = ["#{params[:form][:multiple_documents].size}"] params[:form][:multiple_documents].each do |doc| buffer << "Content-type: #{doc[:type]}" buffer << "File content: #{doc[:tempfile].read}" end buffer.join(' | ') rescue 'No files uploaded' end end end if __FILE__ == $0 Rack::Handler::WEBrick.run TestApp, :Port => 8070 end capybara-2.5.0/lib/capybara/spec/public/0000755000175000017500000000000012573712570017075 5ustar lunarlunarcapybara-2.5.0/lib/capybara/spec/public/test.js0000644000175000017500000000656712573712570020430 0ustar lunarlunarvar activeRequests = 0; $(function() { $('#change').text('I changed it'); $('#drag').draggable(); $('#drop').droppable({ drop: function(event, ui) { ui.draggable.remove(); $(this).html('Dropped!'); } }); $('#clickable').click(function() { var link = $(this); setTimeout(function() { $(link).after('Has been clicked'); $(link).after(''); $(link).after(''); $('#change').remove(); }, 500); return false; }); $('#slow-click').click(function() { var link = $(this); setTimeout(function() { $(link).after('Slow link clicked'); }, 4000); return false; }); $('#waiter').change(function() { activeRequests = 1; setTimeout(function() { activeRequests = 0; }, 500); }); $('#with_focus_event').focus(function() { $('body').append('

Focus Event triggered

'); }); $('#with_change_event').change(function() { $('body').append($('

').text(this.value)); }); $('#checkbox_with_event').click(function() { $('body').append('

Checkbox event triggered

'); }); $('#fire_ajax_request').click(function() { $.ajax({url: "/slow_response", context: document.body, success: function() { $('body').append('

Ajax request done

'); }}); }); $('#reload-link').click(function() { setTimeout(function() { $('#reload-me').replaceWith(''); }, 250) }); $('#reload-list').click(function() { setTimeout(function() { $('#the-list').html('
  • Foo
  • Bar
  • '); }, 550) }); $('#change-title').click(function() { setTimeout(function() { $('title').text('changed title') }, 250) }); $('#click-test').dblclick(function() { $(this).after('Has been double clicked'); }); $('#click-test').bind('contextmenu', function(e) { e.preventDefault(); $(this).after('Has been right clicked'); }); $('#open-alert').click(function() { alert('Alert opened'); $(this).attr('opened', 'true'); }); $('#open-delayed-alert').click(function() { var link = this; setTimeout(function() { alert('Delayed alert opened'); $(link).attr('opened', 'true'); }, 250); }); $('#open-slow-alert').click(function() { var link = this; setTimeout(function() { alert('Delayed alert opened'); $(link).attr('opened', 'true'); }, 3000); }); $('#open-confirm').click(function() { if(confirm('Confirm opened')) { $(this).attr('confirmed', 'true'); } else { $(this).attr('confirmed', 'false'); } }); $('#open-prompt').click(function() { var response = prompt('Prompt opened'); if(response === null) { $(this).attr('response', 'dismissed'); } else { $(this).attr('response', response); } }); $('#delayed-page-change').click(function() { setTimeout(function() { window.location.pathname = '/with_html' }, 500) }) $('#with-key-events').keydown(function(e){ $('#key-events-output').append('keydown:'+e.which+' ') }); }); capybara-2.5.0/lib/capybara/spec/spec_helper.rb0000644000175000017500000000533012573712570020436 0ustar lunarlunarrequire "rspec" require "capybara" require "capybara/rspec" # Required here instead of in rspec_spec to avoid RSpec deprecation warning require "capybara/spec/test_app" require "nokogiri" # Alias be_truthy/be_falsey if not already defined to be able to use in RSpec 2 and 3 unless RSpec::Matchers.method_defined?(:be_truthy) RSpec::Matchers.module_eval do alias be_truthy be_true alias be_falsey be_false alias be_falsy be_false end end module Capybara module SpecHelper class << self def configure(config) config.filter_run_excluding :requires => method(:filter).to_proc config.before { Capybara::SpecHelper.reset! } config.after { Capybara::SpecHelper.reset! } end def reset! Capybara.app = TestApp Capybara.app_host = nil Capybara.default_selector = :xpath Capybara.default_max_wait_time = 1 Capybara.ignore_hidden_elements = true Capybara.exact = false Capybara.exact_options = false Capybara.raise_server_errors = true Capybara.visible_text_only = false Capybara.match = :smart Capybara.wait_on_first_by_default = false end def filter(requires, metadata) if requires and metadata[:capybara_skip] requires.any? do |require| metadata[:capybara_skip].include?(require) end else false end end def spec(name, options={}, &block) @specs ||= [] @specs << [name, options, block] end def run_specs(session, name, options={}) specs = @specs RSpec.describe Capybara::Session, name, options do include Capybara::SpecHelper include Capybara::RSpecMatchers before do @session = session end after do @session.reset_session! end specs.each do |spec_name, spec_options, block| describe spec_name, spec_options do class_eval(&block) end end end end end # class << self def silence_stream(stream) old_stream = stream.dup stream.reopen(RbConfig::CONFIG['host_os'] =~ /rmswin|mingw/ ? 'NUL:' : '/dev/null') stream.sync = true yield ensure stream.reopen(old_stream) end def quietly silence_stream(STDOUT) do silence_stream(STDERR) do yield end end end def extract_results(session) expect(session).to have_xpath("//pre[@id='results']") YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip end end end Dir[File.dirname(__FILE__) + "/session/**/*.rb"].each { |file| require_relative file } capybara-2.5.0/lib/capybara/spec/fixtures/0000755000175000017500000000000012573712570017470 5ustar lunarlunarcapybara-2.5.0/lib/capybara/spec/fixtures/another_test_file.txt0000644000175000017500000000002712573712570023726 0ustar lunarlunarThisIsTheOtherTestFile capybara-2.5.0/lib/capybara/spec/fixtures/capybara.jpg0000644000175000017500000000021512573712570021752 0ustar lunarlunarThis is a jpeg file :) Since it is rendered in the view it doesn't actually contain any binary data, as that would cause Nokogiri to go mad. capybara-2.5.0/lib/capybara/spec/fixtures/test_file.txt0000644000175000017500000000002112573712570022200 0ustar lunarlunarThisIsTheTestFilecapybara-2.5.0/lib/capybara/spec/session/0000755000175000017500000000000012573712570017302 5ustar lunarlunarcapybara-2.5.0/lib/capybara/spec/session/go_forward_spec.rb0000644000175000017500000000071012573712570022770 0ustar lunarlunarCapybara::SpecHelper.spec '#go_forward', :requires => [:js] do it "should fetch a response from the driver from the previous page" do @session.visit('/') expect(@session).to have_content('Hello world!') @session.visit('/foo') expect(@session).to have_content('Another World') @session.go_back expect(@session).to have_content('Hello world!') @session.go_forward expect(@session).to have_content('Another World') end end capybara-2.5.0/lib/capybara/spec/session/has_css_spec.rb0000644000175000017500000002136712573712570022275 0ustar lunarlunarCapybara::SpecHelper.spec '#has_css?' do before do @session.visit('/with_html') end it "should be true if the given selector is on the page" do expect(@session).to have_css("p") expect(@session).to have_css("p a#foo") end it "should be false if the given selector is not on the page" do expect(@session).not_to have_css("abbr") expect(@session).not_to have_css("p a#doesnotexist") expect(@session).not_to have_css("p.nosuchclass") end it "should respect scopes" do @session.within "//p[@id='first']" do expect(@session).to have_css("a#foo") expect(@session).not_to have_css("a#red") end end it "should wait for content to appear", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') expect(@session).to have_css("input[type='submit'][value='New Here']") end context "with between" do it "should be true if the content occurs within the range given" do expect(@session).to have_css("p", :between => 1..4) expect(@session).to have_css("p a#foo", :between => 1..3) expect(@session).to have_css("p a.doesnotexist", :between => 0..8) end it "should be false if the content occurs more or fewer times than range" do expect(@session).not_to have_css("p", :between => 6..11 ) expect(@session).not_to have_css("p a#foo", :between => 4..7) expect(@session).not_to have_css("p a.doesnotexist", :between => 3..8) end end context "with count" do it "should be true if the content occurs the given number of times" do expect(@session).to have_css("p", :count => 3) expect(@session).to have_css("p a#foo", :count => 1) expect(@session).to have_css("p a.doesnotexist", :count => 0) end it "should be false if the content occurs a different number of times than the given" do expect(@session).not_to have_css("p", :count => 6) expect(@session).not_to have_css("p a#foo", :count => 2) expect(@session).not_to have_css("p a.doesnotexist", :count => 1) end it "should coerce count to an integer" do expect(@session).to have_css("p", :count => "3") expect(@session).to have_css("p a#foo", :count => "1") end end context "with maximum" do it "should be true when content occurs same or fewer times than given" do expect(@session).to have_css("h2.head", :maximum => 5) # edge case expect(@session).to have_css("h2", :maximum => 10) expect(@session).to have_css("p a.doesnotexist", :maximum => 1) expect(@session).to have_css("p a.doesnotexist", :maximum => 0) end it "should be false when content occurs more times than given" do expect(@session).not_to have_css("h2.head", :maximum => 4) # edge case expect(@session).not_to have_css("h2", :maximum => 3) expect(@session).not_to have_css("p", :maximum => 1) end it "should coerce maximum to an integer" do expect(@session).to have_css("h2.head", :maximum => "5") # edge case expect(@session).to have_css("h2", :maximum => "10") end end context "with minimum" do it "should be true when content occurs same or more times than given" do expect(@session).to have_css("h2.head", :minimum => 5) # edge case expect(@session).to have_css("h2", :minimum => 3) expect(@session).to have_css("p a.doesnotexist", :minimum => 0) end it "should be false when content occurs fewer times than given" do expect(@session).not_to have_css("h2.head", :minimum => 6) # edge case expect(@session).not_to have_css("h2", :minimum => 8) expect(@session).not_to have_css("p", :minimum => 10) expect(@session).not_to have_css("p a.doesnotexist", :minimum => 1) end it "should coerce minimum to an integer" do expect(@session).to have_css("h2.head", :minimum => "5") # edge case expect(@session).to have_css("h2", :minimum => "3") end end context "with text" do it "should discard all matches where the given string is not contained" do expect(@session).to have_css("p a", :text => "Redirect", :count => 1) expect(@session).not_to have_css("p a", :text => "Doesnotexist") end it "should discard all matches where the given regexp is not matched" do expect(@session).to have_css("p a", :text => /re[dab]i/i, :count => 1) expect(@session).not_to have_css("p a", :text => /Red$/) end end end Capybara::SpecHelper.spec '#has_no_css?' do before do @session.visit('/with_html') end it "should be false if the given selector is on the page" do expect(@session).not_to have_no_css("p") expect(@session).not_to have_no_css("p a#foo") end it "should be true if the given selector is not on the page" do expect(@session).to have_no_css("abbr") expect(@session).to have_no_css("p a#doesnotexist") expect(@session).to have_no_css("p.nosuchclass") end it "should respect scopes" do @session.within "//p[@id='first']" do expect(@session).not_to have_no_css("a#foo") expect(@session).to have_no_css("a#red") end end it "should wait for content to disappear", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') expect(@session).to have_no_css("p#change") end context "with between" do it "should be false if the content occurs within the range given" do expect(@session).not_to have_no_css("p", :between => 1..4) expect(@session).not_to have_no_css("p a#foo", :between => 1..3) expect(@session).not_to have_no_css("p a.doesnotexist", :between => 0..2) end it "should be true if the content occurs more or fewer times than range" do expect(@session).to have_no_css("p", :between => 6..11 ) expect(@session).to have_no_css("p a#foo", :between => 4..7) expect(@session).to have_no_css("p a.doesnotexist", :between => 3..8) end end context "with count" do it "should be false if the content is on the page the given number of times" do expect(@session).not_to have_no_css("p", :count => 3) expect(@session).not_to have_no_css("p a#foo", :count => 1) expect(@session).not_to have_no_css("p a.doesnotexist", :count => 0) end it "should be true if the content is on the page the given number of times" do expect(@session).to have_no_css("p", :count => 6) expect(@session).to have_no_css("p a#foo", :count => 2) expect(@session).to have_no_css("p a.doesnotexist", :count => 1) end it "should coerce count to an integer" do expect(@session).not_to have_no_css("p", :count => "3") expect(@session).not_to have_no_css("p a#foo", :count => "1") end end context "with maximum" do it "should be false when content occurs same or fewer times than given" do expect(@session).not_to have_no_css("h2.head", :maximum => 5) # edge case expect(@session).not_to have_no_css("h2", :maximum => 10) expect(@session).not_to have_no_css("p a.doesnotexist", :maximum => 0) end it "should be true when content occurs more times than given" do expect(@session).to have_no_css("h2.head", :maximum => 4) # edge case expect(@session).to have_no_css("h2", :maximum => 3) expect(@session).to have_no_css("p", :maximum => 1) end it "should coerce maximum to an integer" do expect(@session).not_to have_no_css("h2.head", :maximum => "5") # edge case expect(@session).not_to have_no_css("h2", :maximum => "10") end end context "with minimum" do it "should be false when content occurs same or more times than given" do expect(@session).not_to have_no_css("h2.head", :minimum => 5) # edge case expect(@session).not_to have_no_css("h2", :minimum => 3) expect(@session).not_to have_no_css("p a.doesnotexist", :minimum => 0) end it "should be true when content occurs fewer times than given" do expect(@session).to have_no_css("h2.head", :minimum => 6) # edge case expect(@session).to have_no_css("h2", :minimum => 8) expect(@session).to have_no_css("p", :minimum => 15) expect(@session).to have_no_css("p a.doesnotexist", :minimum => 1) end it "should coerce minimum to an integer" do expect(@session).not_to have_no_css("h2.head", :minimum => "4") # edge case expect(@session).not_to have_no_css("h2", :minimum => "3") end end context "with text" do it "should discard all matches where the given string is not contained" do expect(@session).not_to have_no_css("p a", :text => "Redirect", :count => 1) expect(@session).to have_no_css("p a", :text => "Doesnotexist") end it "should discard all matches where the given regexp is not matched" do expect(@session).not_to have_no_css("p a", :text => /re[dab]i/i, :count => 1) expect(@session).to have_no_css("p a", :text => /Red$/) end end end capybara-2.5.0/lib/capybara/spec/session/click_link_or_button_spec.rb0000644000175000017500000000674712573712570025054 0ustar lunarlunarCapybara::SpecHelper.spec '#click_link_or_button' do it "should click on a link" do @session.visit('/with_html') @session.click_link_or_button('labore') expect(@session).to have_content('Bar') end it "should click on a button" do @session.visit('/form') @session.click_link_or_button('awe123') expect(extract_results(@session)['first_name']).to eq('John') end it "should click on a button with no type attribute" do @session.visit('/form') @session.click_link_or_button('no_type') expect(extract_results(@session)['first_name']).to eq('John') end it "should be aliased as click_on" do @session.visit('/form') @session.click_on('awe123') expect(extract_results(@session)['first_name']).to eq('John') end it "should wait for asynchronous load", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') @session.click_link_or_button('Has been clicked') end it "casts to string" do @session.visit('/form') @session.click_link_or_button(:'awe123') expect(extract_results(@session)['first_name']).to eq('John') end context "with :exact option" do context "when `true`" do it "clicks on approximately matching link" do @session.visit('/with_html') @session.click_link_or_button('abore', :exact => false) expect(@session).to have_content('Bar') end it "clicks on approximately matching button" do @session.visit('/form') @session.click_link_or_button('awe') expect(extract_results(@session)['first_name']).to eq('John') end end context "when `false`" do it "does not click on link which matches approximately" do @session.visit('/with_html') msg = "Unable to find link or button \"abore\"" expect do @session.click_link_or_button('abore', :exact => true) end.to raise_error(Capybara::ElementNotFound, msg) end it "does not click on approximately matching button" do @session.visit('/form') msg = "Unable to find link or button \"awe\"" expect do @session.click_link_or_button('awe', :exact => true) end.to raise_error(Capybara::ElementNotFound, msg) end end end context "with a locator that doesn't exist" do it "should raise an error" do @session.visit('/with_html') msg = "Unable to find link or button \"does not exist\"" expect do @session.click_link_or_button('does not exist') end.to raise_error(Capybara::ElementNotFound, msg) end end context "with :disabled option" do it "ignores disabled buttons when false" do @session.visit('/form') expect do @session.click_link_or_button('Disabled button', :disabled => false) end.to raise_error(Capybara::ElementNotFound) end it "ignores disabled buttons by default" do @session.visit('/form') expect do @session.click_link_or_button('Disabled button') end.to raise_error(Capybara::ElementNotFound) end it "happily clicks on links which incorrectly have the disabled attribute" do @session.visit('/with_html') @session.click_link_or_button('Disabled link') expect(@session).to have_content("Bar") end it "does nothing when button is disabled" do @session.visit('/form') expect do @session.click_link_or_button('Disabled button', :disabled => false) end.to raise_error(Capybara::ElementNotFound) end end end capybara-2.5.0/lib/capybara/spec/session/headers.rb0000644000175000017500000000037312573712570021245 0ustar lunarlunarCapybara::SpecHelper.spec '#response_headers' do it "should return response headers", :requires => [:response_headers] do @session.visit('/with_simple_html') expect(@session.response_headers['Content-Type']).to match %r(text/html) end end capybara-2.5.0/lib/capybara/spec/session/has_select_spec.rb0000644000175000017500000002004412573712570022753 0ustar lunarlunarCapybara::SpecHelper.spec '#has_select?' do before { @session.visit('/form') } it "should be true if the field is on the page" do expect(@session).to have_select('Locale') expect(@session).to have_select('form_region') expect(@session).to have_select('Languages') expect(@session).to have_select(:'Languages') end it "should be false if the field is not on the page" do expect(@session).not_to have_select('Monkey') end context 'with selected value' do it "should be true if a field with the given value is on the page" do expect(@session).to have_select('form_locale', :selected => 'English') expect(@session).to have_select('Region', :selected => 'Norway') expect(@session).to have_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns' ]) end it "should be false if the given field is not on the page" do expect(@session).not_to have_select('Locale', :selected => 'Swedish') expect(@session).not_to have_select('Does not exist', :selected => 'John') expect(@session).not_to have_select('City', :selected => 'Not there') expect(@session).not_to have_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns', 'Nonexistant' ]) expect(@session).not_to have_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Boxers', 'Commando', "Frenchman's Pantalons", 'Long Johns' ]) expect(@session).not_to have_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs','Commando', "Frenchman's Pantalons" ]) end it "should be true after the given value is selected" do @session.select('Swedish', :from => 'Locale') expect(@session).to have_select('Locale', :selected => 'Swedish') end it "should be false after a different value is selected" do @session.select('Swedish', :from => 'Locale') expect(@session).not_to have_select('Locale', :selected => 'English') end it "should be true after the given values are selected" do @session.select('Boxers', :from => 'Underwear') expect(@session).to have_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Boxers', 'Commando', "Frenchman's Pantalons", 'Long Johns' ]) end it "should be false after one of the values is unselected" do @session.unselect('Briefs', :from => 'Underwear') expect(@session).not_to have_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns' ]) end end context 'with exact options' do it "should be true if a field with the given options is on the page" do expect(@session).to have_select('Region', :options => ['Norway', 'Sweden', 'Finland']) expect(@session).to have_select('Tendency', :options => []) end it "should be false if the given field is not on the page" do expect(@session).not_to have_select('Locale', :options => ['Swedish']) expect(@session).not_to have_select('Does not exist', :options => ['John']) expect(@session).not_to have_select('City', :options => ['London', 'Made up city']) expect(@session).not_to have_select('Region', :options => ['Norway', 'Sweden']) expect(@session).not_to have_select('Region', :options => ['Norway', 'Norway', 'Norway']) end end context 'with partial options' do it "should be true if a field with the given partial options is on the page" do expect(@session).to have_select('Region', :with_options => ['Norway', 'Sweden']) expect(@session).to have_select('City', :with_options => ['London']) end it "should be false if a field with the given partial options is not on the page" do expect(@session).not_to have_select('Locale', :with_options => ['Uruguayan']) expect(@session).not_to have_select('Does not exist', :with_options => ['John']) expect(@session).not_to have_select('Region', :with_options => ['Norway', 'Sweden', 'Finland', 'Latvia']) end end end Capybara::SpecHelper.spec '#has_no_select?' do before { @session.visit('/form') } it "should be false if the field is on the page" do expect(@session).not_to have_no_select('Locale') expect(@session).not_to have_no_select('form_region') expect(@session).not_to have_no_select('Languages') end it "should be true if the field is not on the page" do expect(@session).to have_no_select('Monkey') end context 'with selected value' do it "should be false if a field with the given value is on the page" do expect(@session).not_to have_no_select('form_locale', :selected => 'English') expect(@session).not_to have_no_select('Region', :selected => 'Norway') expect(@session).not_to have_no_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns' ]) end it "should be true if the given field is not on the page" do expect(@session).to have_no_select('Locale', :selected => 'Swedish') expect(@session).to have_no_select('Does not exist', :selected => 'John') expect(@session).to have_no_select('City', :selected => 'Not there') expect(@session).to have_no_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns', 'Nonexistant' ]) expect(@session).to have_no_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Boxers', 'Commando', "Frenchman's Pantalons", 'Long Johns' ]) expect(@session).to have_no_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs','Commando', "Frenchman's Pantalons" ]) end it "should be false after the given value is selected" do @session.select('Swedish', :from => 'Locale') expect(@session).not_to have_no_select('Locale', :selected => 'Swedish') end it "should be true after a different value is selected" do @session.select('Swedish', :from => 'Locale') expect(@session).to have_no_select('Locale', :selected => 'English') end it "should be false after the given values are selected" do @session.select('Boxers', :from => 'Underwear') expect(@session).not_to have_no_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Boxers', 'Commando', "Frenchman's Pantalons", 'Long Johns' ]) end it "should be true after one of the values is unselected" do @session.unselect('Briefs', :from => 'Underwear') expect(@session).to have_no_select('Underwear', :selected => [ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns' ]) end end context 'with exact options' do it "should be false if a field with the given options is on the page" do expect(@session).not_to have_no_select('Region', :options => ['Norway', 'Sweden', 'Finland']) end it "should be true if the given field is not on the page" do expect(@session).to have_no_select('Locale', :options => ['Swedish']) expect(@session).to have_no_select('Does not exist', :options => ['John']) expect(@session).to have_no_select('City', :options => ['London', 'Made up city']) expect(@session).to have_no_select('Region', :options => ['Norway', 'Sweden']) expect(@session).to have_no_select('Region', :options => ['Norway', 'Norway', 'Norway']) end end context 'with partial options' do it "should be false if a field with the given partial options is on the page" do expect(@session).not_to have_no_select('Region', :with_options => ['Norway', 'Sweden']) expect(@session).not_to have_no_select('City', :with_options => ['London']) end it "should be true if a field with the given partial options is not on the page" do expect(@session).to have_no_select('Locale', :with_options => ['Uruguayan']) expect(@session).to have_no_select('Does not exist', :with_options => ['John']) expect(@session).to have_no_select('Region', :with_options => ['Norway', 'Sweden', 'Finland', 'Latvia']) end end end capybara-2.5.0/lib/capybara/spec/session/check_spec.rb0000644000175000017500000000733312573712570021724 0ustar lunarlunarCapybara::SpecHelper.spec "#check" do before do @session.visit('/form') end describe "'checked' attribute" do it "should be true if checked" do @session.check("Terms of Use") expect(@session.find(:xpath, "//input[@id='form_terms_of_use']")['checked']).to be_truthy end it "should be false if unchecked" do expect(@session.find(:xpath, "//input[@id='form_terms_of_use']")['checked']).to be_falsey end end it "should trigger associated events", :requires => [:js] do @session.visit('/with_js') @session.check('checkbox_with_event') expect(@session).to have_css('#checkbox_event_triggered'); end describe "checking" do it "should not change an already checked checkbox" do expect(@session.find(:xpath, "//input[@id='form_pets_dog']")['checked']).to be_truthy @session.check('form_pets_dog') expect(@session.find(:xpath, "//input[@id='form_pets_dog']")['checked']).to be_truthy end it "should check an unchecked checkbox" do expect(@session.find(:xpath, "//input[@id='form_pets_cat']")['checked']).to be_falsey @session.check('form_pets_cat') expect(@session.find(:xpath, "//input[@id='form_pets_cat']")['checked']).to be_truthy end end describe "unchecking" do it "should not change an already unchecked checkbox" do expect(@session.find(:xpath, "//input[@id='form_pets_cat']")['checked']).to be_falsey @session.uncheck('form_pets_cat') expect(@session.find(:xpath, "//input[@id='form_pets_cat']")['checked']).to be_falsey end it "should uncheck a checked checkbox" do expect(@session.find(:xpath, "//input[@id='form_pets_dog']")['checked']).to be_truthy @session.uncheck('form_pets_dog') expect(@session.find(:xpath, "//input[@id='form_pets_dog']")['checked']).to be_falsey end end it "should check a checkbox by id" do @session.check("form_pets_cat") @session.click_button('awesome') expect(extract_results(@session)['pets']).to include('dog', 'cat', 'hamster') end it "should check a checkbox by label" do @session.check("Cat") @session.click_button('awesome') expect(extract_results(@session)['pets']).to include('dog', 'cat', 'hamster') end it "casts to string" do @session.check(:"form_pets_cat") @session.click_button('awesome') expect(extract_results(@session)['pets']).to include('dog', 'cat', 'hamster') end context "with a locator that doesn't exist" do it "should raise an error" do msg = "Unable to find checkbox \"does not exist\"" expect do @session.check('does not exist') end.to raise_error(Capybara::ElementNotFound, msg) end end context "with a disabled checkbox" do it "should raise an error" do expect do @session.check('Disabled Checkbox') end.to raise_error(Capybara::ElementNotFound) end end context "with :exact option" do it "should accept partial matches when false" do @session.check('Ham', :exact => false) @session.click_button('awesome') expect(extract_results(@session)['pets']).to include('hamster') end it "should not accept partial matches when true" do expect do @session.check('Ham', :exact => true) end.to raise_error(Capybara::ElementNotFound) end end context "with `option` option" do it "can check boxes by their value" do @session.check('form[pets][]', :option => "cat") @session.click_button('awesome') expect(extract_results(@session)['pets']).to include('cat') end it "should raise an error if option not found" do expect do @session.check('form[pets][]', :option => "elephant") end.to raise_error(Capybara::ElementNotFound) end end end capybara-2.5.0/lib/capybara/spec/session/screenshot_spec.rb0000644000175000017500000000062712573712570023023 0ustar lunarlunar#coding: US-ASCII Capybara::SpecHelper.spec "#save_screenshot" do let(:image_path) { File.join(Dir.tmpdir, 'capybara-screenshot.png') } before do @session.visit '/' end it "should generate PNG file", :requires => [:screenshot] do path = @session.save_screenshot image_path magic = File.read(image_path, 4) expect(magic).to eq "\x89PNG" expect(path).to eq image_path end end capybara-2.5.0/lib/capybara/spec/session/fill_in_spec.rb0000644000175000017500000001510512573712570022257 0ustar lunarlunarCapybara::SpecHelper.spec "#fill_in" do before do @session.visit('/form') end it "should fill in a text field by id" do @session.fill_in('form_first_name', :with => 'Harry') @session.click_button('awesome') expect(extract_results(@session)['first_name']).to eq('Harry') end it "should fill in a text field by name" do @session.fill_in('form[last_name]', :with => 'Green') @session.click_button('awesome') expect(extract_results(@session)['last_name']).to eq('Green') end it "should fill in a text field by label without for" do @session.fill_in('First Name', :with => 'Harry') @session.click_button('awesome') expect(extract_results(@session)['first_name']).to eq('Harry') end it "should fill in a url field by label without for" do @session.fill_in('Html5 Url', :with => 'http://www.avenueq.com') @session.click_button('html5_submit') expect(extract_results(@session)['html5_url']).to eq('http://www.avenueq.com') end it "should fill in a textarea by id" do @session.fill_in('form_description', :with => 'Texty text') @session.click_button('awesome') expect(extract_results(@session)['description']).to eq('Texty text') end it "should fill in a textarea by label" do @session.fill_in('Description', :with => 'Texty text') @session.click_button('awesome') expect(extract_results(@session)['description']).to eq('Texty text') end it "should fill in a textarea by name" do @session.fill_in('form[description]', :with => 'Texty text') @session.click_button('awesome') expect(extract_results(@session)['description']).to eq('Texty text') end it "should fill in a password field by id" do @session.fill_in('form_password', :with => 'supasikrit') @session.click_button('awesome') expect(extract_results(@session)['password']).to eq('supasikrit') end it "should handle HTML in a textarea" do @session.fill_in('form_description', :with => 'is very secret!') @session.click_button('awesome') expect(extract_results(@session)['description']).to eq('is very secret!') end it "should handle newlines in a textarea" do @session.fill_in('form_description', :with => "\nSome text\n") @session.click_button('awesome') expect(extract_results(@session)['description']).to eq("\r\nSome text\r\n") end it "should fill in a field with a custom type" do @session.fill_in('Schmooo', :with => 'Schmooo is the game') @session.click_button('awesome') expect(extract_results(@session)['schmooo']).to eq('Schmooo is the game') end it "should fill in a field without a type" do @session.fill_in('Phone', :with => '+1 555 7022') @session.click_button('awesome') expect(extract_results(@session)['phone']).to eq('+1 555 7022') end it "should fill in a text field respecting its maxlength attribute" do @session.fill_in('Zipcode', :with => '52071350') @session.click_button('awesome') expect(extract_results(@session)['zipcode']).to eq('52071') end it "should fill in a password field by name" do @session.fill_in('form[password]', :with => 'supasikrit') @session.click_button('awesome') expect(extract_results(@session)['password']).to eq('supasikrit') end it "should fill in a password field by label" do @session.fill_in('Password', :with => 'supasikrit') @session.click_button('awesome') expect(extract_results(@session)['password']).to eq('supasikrit') end it "should fill in a password field by name" do @session.fill_in('form[password]', :with => 'supasikrit') @session.click_button('awesome') expect(extract_results(@session)['password']).to eq('supasikrit') end it "should throw an exception if a hash containing 'with' is not provided" do expect {@session.fill_in 'Name', 'ignu'}.to raise_error(RuntimeError, /with/) end it "should wait for asynchronous load", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') @session.fill_in('new_field', :with => 'Testing...') end it "casts to string" do @session.fill_in(:'form_first_name', :with => :'Harry') @session.click_button('awesome') expect(extract_results(@session)['first_name']).to eq('Harry') end it "casts to string if field has maxlength" do @session.fill_in(:'form_zipcode', :with => 1234567) @session.click_button('awesome') expect(extract_results(@session)['zipcode']).to eq('12345') end context 'on a pre-populated textfield with a reformatting onchange', :requires => [:js] do it 'should only trigger onchange once' do @session.visit('/with_js') @session.fill_in('with_change_event', :with => 'some value') # click outside the field to trigger the change event @session.find(:css, 'body').click expect(@session.find(:css, '.change_event_triggered', :match => :one)).to have_text 'some value' end it 'should trigger change when clearing field' do @session.visit('/with_js') @session.fill_in('with_change_event', :with => '') # click outside the field to trigger the change event @session.find(:css, 'body').click expect(@session).to have_selector(:css, '.change_event_triggered', :match => :one) end end context "with ignore_hidden_fields" do before { Capybara.ignore_hidden_elements = true } after { Capybara.ignore_hidden_elements = false } it "should not find a hidden field" do msg = "Unable to find field \"Super Secret\"" expect do @session.fill_in('Super Secret', :with => '777') end.to raise_error(Capybara::ElementNotFound, msg) end end context "with a locator that doesn't exist" do it "should raise an error" do msg = "Unable to find field \"does not exist\"" expect do @session.fill_in('does not exist', :with => 'Blah blah') end.to raise_error(Capybara::ElementNotFound, msg) end end context "on a disabled field" do it "should raise an error" do expect do @session.fill_in('Disabled Text Field', :with => 'Blah blah') end.to raise_error(Capybara::ElementNotFound) end end context "with :exact option" do it "should accept partial matches when false" do @session.fill_in("Explanation", :with => "Dude", :exact => false) @session.click_button("awesome") expect(extract_results(@session)["name_explanation"]).to eq("Dude") end it "should not accept partial matches when true" do expect do @session.fill_in("Explanation", :with => "Dude", :exact => true) end.to raise_error(Capybara::ElementNotFound) end end end capybara-2.5.0/lib/capybara/spec/session/all_spec.rb0000644000175000017500000001404612573712570021416 0ustar lunarlunarCapybara::SpecHelper.spec "#all" do before do @session.visit('/with_html') end it "should find all elements using the given locator" do expect(@session.all('//p').size).to eq(3) expect(@session.all('//h1').first.text).to eq('This is a test') expect(@session.all("//input[@id='test_field']").first[:value]).to eq('monkey') end it "should return an empty array when nothing was found" do expect(@session.all('//div[@id="nosuchthing"]')).to be_empty end it "should accept an XPath instance" do @session.visit('/form') @xpath = XPath::HTML.fillable_field('Name') @result = @session.all(@xpath).map { |r| r.value } expect(@result).to include('Smith', 'John', 'John Smith') end it "should raise an error when given invalid options" do expect { @session.all('//p', :schmoo => "foo") }.to raise_error(ArgumentError) end context "with css selectors" do it "should find all elements using the given selector" do expect(@session.all(:css, 'h1').first.text).to eq('This is a test') expect(@session.all(:css, "input[id='test_field']").first[:value]).to eq('monkey') end it "should find all elements when given a list of selectors" do expect(@session.all(:css, 'h1, p').size).to eq(4) end end context "with xpath selectors" do it "should find the first element using the given locator" do expect(@session.all(:xpath, '//h1').first.text).to eq('This is a test') expect(@session.all(:xpath, "//input[@id='test_field']").first[:value]).to eq('monkey') end end context "with css as default selector" do before { Capybara.default_selector = :css } it "should find the first element using the given locator" do expect(@session.all('h1').first.text).to eq('This is a test') expect(@session.all("input[id='test_field']").first[:value]).to eq('monkey') end end context "with visible filter" do it "should only find visible nodes when true" do expect(@session.all(:css, "a.simple", :visible => true).size).to eq(1) end it "should find nodes regardless of whether they are invisible when false" do expect(@session.all(:css, "a.simple", :visible => false).size).to eq(2) end it "should default to Capybara.ignore_hidden_elements" do Capybara.ignore_hidden_elements = true expect(@session.all(:css, "a.simple").size).to eq(1) Capybara.ignore_hidden_elements = false expect(@session.all(:css, "a.simple").size).to eq(2) end end context 'with element count filters' do context ':count' do it 'should succeed when the number of elements founds matches the expectation' do expect { @session.all(:css, 'h1, p', :count => 4) }.to_not raise_error end it 'should raise ExpectationNotMet when the number of elements founds does not match the expectation' do expect { @session.all(:css, 'h1, p', :count => 5) }.to raise_error(Capybara::ExpectationNotMet) end end context ':minimum' do it 'should succeed when the number of elements founds matches the expectation' do expect { @session.all(:css, 'h1, p', :minimum => 0) }.to_not raise_error end it 'should raise ExpectationNotMet when the number of elements founds does not match the expectation' do expect { @session.all(:css, 'h1, p', :minimum => 5) }.to raise_error(Capybara::ExpectationNotMet) end end context ':maximum' do it 'should succeed when the number of elements founds matches the expectation' do expect { @session.all(:css, 'h1, p', :maximum => 4) }.to_not raise_error end it 'should raise ExpectationNotMet when the number of elements founds does not match the expectation' do expect { @session.all(:css, 'h1, p', :maximum => 0) }.to raise_error(Capybara::ExpectationNotMet) end end context ':between' do it 'should succeed when the number of elements founds matches the expectation' do expect { @session.all(:css, 'h1, p', :between => 2..7) }.to_not raise_error end it 'should raise ExpectationNotMet when the number of elements founds does not match the expectation' do expect { @session.all(:css, 'h1, p', :between => 0..3) }.to raise_error(Capybara::ExpectationNotMet) end end context 'with multiple count filters' do it 'ignores other filters when :count is specified' do o = {:count => 4, :minimum => 5, :maximum => 0, :between => 0..3} expect { @session.all(:css, 'h1, p', o) }.to_not raise_error end context 'with no :count expectation' do it 'fails if :minimum is not met' do o = {:minimum => 5, :maximum => 4, :between => 2..7} expect { @session.all(:css, 'h1, p', o) }.to raise_error(Capybara::ExpectationNotMet) end it 'fails if :maximum is not met' do o = {:minimum => 0, :maximum => 0, :between => 2..7} expect { @session.all(:css, 'h1, p', o) }.to raise_error(Capybara::ExpectationNotMet) end it 'fails if :between is not met' do o = {:minimum => 0, :maximum => 4, :between => 0..3} expect { @session.all(:css, 'h1, p', o) }.to raise_error(Capybara::ExpectationNotMet) end it 'succeeds if all combineable expectations are met' do o = {:minimum => 0, :maximum => 4, :between => 2..7} expect { @session.all(:css, 'h1, p', o) }.to_not raise_error end end end end context "within a scope" do before do @session.visit('/with_scope') end it "should find any element using the given locator" do @session.within(:xpath, "//div[@id='for_bar']") do expect(@session.all('.//li').size).to eq(2) end end end it "should have #find_all as an alias" do expect(Capybara::Node::Finders.instance_method(:all)).to eq Capybara::Node::Finders.instance_method(:find_all) expect(@session.find_all('//p').size).to eq(3) end end capybara-2.5.0/lib/capybara/spec/session/execute_script_spec.rb0000644000175000017500000000050112573712570023663 0ustar lunarlunarCapybara::SpecHelper.spec "#execute_script", :requires => [:js] do it "should execute the given script and return nothing" do @session.visit('/with_js') expect(@session.execute_script("$('#change').text('Funky Doodle')")).to be_nil expect(@session).to have_css('#change', :text => 'Funky Doodle') end end capybara-2.5.0/lib/capybara/spec/session/current_url_spec.rb0000644000175000017500000000577612573712570023224 0ustar lunarlunarrequire "capybara/spec/test_app" Capybara::SpecHelper.spec '#current_url, #current_path, #current_host' do before :all do @servers = 2.times.map { Capybara::Server.new(TestApp.clone).boot } # sanity check expect(@servers[0].port).not_to eq(@servers[1].port) expect(@servers.map { |s| s.port }).not_to include 80 end def bases @servers.map { |s| "http://#{s.host}:#{s.port}" } end def should_be_on server_index, path="/host", scheme="http" #This delay is to give fully async drivers (selenium w/chromedriver) time for the browser #to get to its destination - should be removed when we have a waiting current_url matcher sleep 0.1 # remove and adjust tests when a waiting current_url/path matcher is implemented # Check that we are on /host on the given server s = @servers[server_index] expect(@session.current_url.chomp('?')).to eq("#{scheme}://#{s.host}:#{s.port}#{path}") expect(@session.current_host).to eq("#{scheme}://#{s.host}") # no port expect(@session.current_path).to eq(path) if path == '/host' # Server should agree with us expect(@session).to have_content("Current host is #{scheme}://#{s.host}:#{s.port}") end end def visit_host_links @session.visit("#{bases[0]}/host_links?absolute_host=#{bases[1]}") end it "is affected by visiting a page directly" do @session.visit("#{bases[0]}/host") should_be_on 0 end it "returns to the app host when visiting a relative url" do Capybara.app_host = bases[1] @session.visit("#{bases[0]}/host") should_be_on 0 @session.visit('/host') should_be_on 1 Capybara.app_host = nil end it "is affected by setting Capybara.app_host" do Capybara.app_host = bases[0] @session.visit("/host") should_be_on 0 Capybara.app_host = bases[1] @session.visit("/host") should_be_on 1 Capybara.app_host = nil end it "is unaffected by following a relative link" do visit_host_links @session.click_link("Relative Host") should_be_on 0 end it "is affected by following an absolute link" do visit_host_links @session.click_link("Absolute Host") should_be_on 1 end it "is unaffected by posting through a relative form" do visit_host_links @session.click_button("Relative Host") should_be_on 0 end it "is affected by posting through an absolute form" do visit_host_links @session.click_button("Absolute Host") should_be_on 1 end it "is affected by following a redirect" do @session.visit("#{bases[0]}/redirect") should_be_on 0, "/landed" end it "is affected by pushState", :requires => [:js] do @session.visit("/with_js") @session.execute_script("window.history.pushState({}, '', '/pushed')") expect(@session.current_path).to eq("/pushed") end it "is affected by replaceState", :requires => [:js] do @session.visit("/with_js") @session.execute_script("window.history.replaceState({}, '', '/replaced')") expect(@session.current_path).to eq("/replaced") end end capybara-2.5.0/lib/capybara/spec/session/window/0000755000175000017500000000000012573712570020611 5ustar lunarlunarcapybara-2.5.0/lib/capybara/spec/session/window/open_new_window_spec.rb0000644000175000017500000000145712573712570025360 0ustar lunarlunarCapybara::SpecHelper.spec '#open_new_window', requires: [:windows] do before(:each) do @window = @session.current_window @session.visit('/with_windows') end after(:each) do (@session.windows - [@window]).each do |w| @session.switch_to_window w w.close end @session.switch_to_window(@window) end it 'should open new window with blank url and title' do window = @session.open_new_window @session.switch_to_window(window) expect(['', 'about:blank']).to include(@session.title) expect(@session.current_url).to eq('about:blank') end it 'should open window with changeable content' do window = @session.open_new_window @session.within_window window do @session.visit '/with_html' expect(@session).to have_css('#first') end end end capybara-2.5.0/lib/capybara/spec/session/window/current_window_spec.rb0000644000175000017500000000132512573712570025222 0ustar lunarlunarCapybara::SpecHelper.spec '#current_window', requires: [:windows] do before(:each) do @window = @session.current_window @session.visit('/with_windows') end after(:each) do (@session.windows - [@window]).each do |w| @session.switch_to_window w w.close end @session.switch_to_window(@window) end it 'should return window' do expect(@session.current_window).to be_instance_of(Capybara::Window) end it "should be modified by switching to another window" do window = @session.window_opened_by { @session.find(:css, '#openWindow').click } expect do @session.switch_to_window(window) end.to change { @session.current_window }.from(@window).to(window) end end capybara-2.5.0/lib/capybara/spec/session/window/window_opened_by_spec.rb0000644000175000017500000000607012573712570025506 0ustar lunarlunarCapybara::SpecHelper.spec '#window_opened_by', requires: [:windows] do before(:each) do @window = @session.current_window @session.visit('/with_windows') end after(:each) do (@session.windows - [@window]).each do |w| @session.switch_to_window w w.close end @session.switch_to_window(@window) end let(:zero_windows_message) { "block passed to #window_opened_by opened 0 windows instead of 1" } let(:two_windows_message) { "block passed to #window_opened_by opened 2 windows instead of 1" } context 'with :wait option' do it 'should raise error if value of :wait is less than timeout' do # So large value is used as `driver.window_handles` takes up to 800 ms on Travis Capybara.using_wait_time 2 do button=@session.find(:css, '#openWindowWithLongerTimeout') expect do @session.window_opened_by(wait: 0.8) do button.click end end.to raise_error(Capybara::WindowError, zero_windows_message) end @session.document.synchronize(2, errors: [Capybara::CapybaraError]) do raise Capybara::CapybaraError if @session.windows.size != 2 end end it 'should find window if value of :wait is more than timeout' do button = @session.find(:css, '#openWindowWithTimeout') Capybara.using_wait_time 0.1 do window = @session.window_opened_by(wait: 1.5) do button.click end expect(window).to be_instance_of(Capybara::Window) end end end context 'without :wait option' do it 'should raise error if default_max_wait_time is less than timeout' do button = @session.find(:css, '#openWindowWithTimeout') Capybara.using_wait_time 0.4 do expect do @session.window_opened_by do button.click end end.to raise_error(Capybara::WindowError, zero_windows_message) end @session.document.synchronize(2, errors: [Capybara::CapybaraError]) do raise Capybara::CapybaraError if @session.windows.size != 2 end end it 'should find window if default_max_wait_time is more than timeout' do button = @session.find(:css, '#openWindowWithTimeout') Capybara.using_wait_time 1.5 do window = @session.window_opened_by do button.click end expect(window).to be_instance_of(Capybara::Window) end end end it 'should raise error when two windows have been opened by block' do button = @session.find(:css, '#openTwoWindows') expect do @session.window_opened_by do button.click end end.to raise_error(Capybara::WindowError, two_windows_message) @session.document.synchronize(2, errors: [Capybara::CapybaraError]) do raise Capybara::CapybaraError if @session.windows.size != 3 end end it 'should raise error when no windows were opened by block' do button = @session.find(:css, '#doesNotOpenWindows') expect do @session.window_opened_by do button.click end end.to raise_error(Capybara::WindowError, zero_windows_message) end end capybara-2.5.0/lib/capybara/spec/session/window/switch_to_window_spec.rb0000644000175000017500000001121112573712570025536 0ustar lunarlunarCapybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do before(:each) do @window = @session.current_window @session.visit('/with_windows') end after(:each) do (@session.windows - [@window]).each do |w| @session.switch_to_window w w.close end @session.switch_to_window(@window) end it "should raise error when invoked without args" do expect do @session.switch_to_window end.to raise_error(ArgumentError, "`switch_to_window`: either window or block should be provided") end it "should raise error when invoked with window and block" do expect do @session.switch_to_window(@window) { @session.title == 'Title of the first popup' } end.to raise_error(ArgumentError, "`switch_to_window` can take either a block or a window, not both") end context "with an instance of Capybara::Window" do it "should be able to switch to window" do window = @session.open_new_window expect(@session.title).to eq('With Windows') @session.switch_to_window(window) expect(['', 'about:blank']).to include(@session.title) end it "should raise error when closed window is passed" do original_window = @session.current_window new_window = @session.open_new_window @session.switch_to_window(new_window) new_window.close @session.switch_to_window(original_window) expect do @session.switch_to_window(new_window) end.to raise_error(@session.driver.no_such_window_error) end end context "with block" do before(:each) do @session.find(:css, '#openTwoWindows').click sleep(0.2) # wait for the windows to open end it "should be able to switch to current window" do @session.switch_to_window { @session.title == 'With Windows' } expect(@session).to have_css('#openTwoWindows') end it "should find the div in another window" do @session.switch_to_window { @session.title == 'Title of popup two' } expect(@session).to have_css('#divInPopupTwo') end it "should be able to switch multiple times" do @session.switch_to_window { @session.title == 'Title of the first popup' } expect(@session).to have_css('#divInPopupOne') @session.switch_to_window { @session.title == 'Title of popup two' } expect(@session).to have_css('#divInPopupTwo') end it "should return window" do window = @session.switch_to_window { @session.title == 'Title of popup two' } expect((@session.windows - [@window])).to include(window) end it "should raise error when invoked inside `within` as it's nonsense" do expect do @session.within(:css, '#doesNotOpenWindows') do @session.switch_to_window { @session.title == 'With Windows' } end end.to raise_error(Capybara::ScopeError, "`switch_to_window` is not supposed to be invoked from `within`'s, `within_frame`'s' or `within_window`'s' block.") end it "should raise error when invoked inside `within_frame` as it's nonsense" do expect do @session.within_frame('frameOne') do @session.switch_to_window { @session.title == 'With Windows' } end end.to raise_error(Capybara::ScopeError, "`switch_to_window` is not supposed to be invoked from `within`'s, `within_frame`'s' or `within_window`'s' block.") end it "should raise error when invoked inside `within_window` as it's nonsense" do window = (@session.windows - [@window]).first expect do @session.within_window window do @session.switch_to_window { @session.title == 'With Windows' } end end.to raise_error(Capybara::ScopeError, "`switch_to_window` is not supposed to be invoked from `within`'s, `within_frame`'s' or `within_window`'s' block.") end it "should raise error if window matching block wasn't found" do original = @session.current_window expect do @session.switch_to_window { @session.title == 'A title' } end.to raise_error(Capybara::WindowError, "Could not find a window matching block/lambda") expect(@session.current_window).to eq(original) end it "should switch to original window if error is raised inside block" do original = @session.switch_to_window(@session.windows[1]) expect do @session.switch_to_window { raise 'error' } end.to raise_error(StandardError, 'error') expect(@session.current_window).to eq(original) end end it "should wait for window to appear" do @session.find(:css, '#openWindowWithTimeout').click expect do @session.switch_to_window { @session.title == 'Title of the first popup'} end.not_to raise_error end end capybara-2.5.0/lib/capybara/spec/session/window/within_window_spec.rb0000644000175000017500000001567612573712570025060 0ustar lunarlunarCapybara::SpecHelper.spec '#within_window', requires: [:windows] do before(:each) do @window = @session.current_window @session.visit('/with_windows') @session.find(:css, '#openTwoWindows').click @session.document.synchronize(3, errors: [Capybara::CapybaraError]) do raise Capybara::CapybaraError if @session.windows.size != 3 end end after(:each) do (@session.windows - [@window]).each do |w| @session.switch_to_window w w.close end @session.switch_to_window(@window) end context "with an instance of Capybara::Window" do it "should not invoke driver#switch_to_window when given current window" do # switch_to_window is invoked in after hook expect(@session.driver).to receive(:switch_to_window).exactly(3).times.and_call_original @session.within_window @window do expect(@session.title).to eq('With Windows') end end it "should be able to switch to another window" do window = (@session.windows - [@window]).first expect(@session.driver).to receive(:switch_to_window).exactly(5).times.and_call_original @session.within_window window do expect(['Title of the first popup', 'Title of popup two']).to include(@session.title) end expect(@session.title).to eq('With Windows') end it "returns value from the block" do window = (@session.windows - [@window]).first value = @session.within_window window do 43252003274489856000 end expect(value).to eq(43252003274489856000) end it "should switch back if exception was raised inside block" do window = (@session.windows - [@window]).first expect do @session.within_window(window) do @session.within 'html' do raise 'some error' end end end.to raise_error(StandardError, 'some error') expect(@session.current_window).to eq(@window) expect(@session).to have_css('#doesNotOpenWindows') expect(@session.send(:scopes)).to eq([nil]) end it "should leave correct scopes after execution in case of error" do window = (@session.windows - [@window]).first expect do @session.within 'html' do @session.within_window(window) {} end end.to raise_error(Capybara::ScopeError) expect(@session.current_window).to eq(@window) expect(@session).to have_css('#doesNotOpenWindows') expect(@session.send(:scopes)).to eq([nil]) end it 'should raise error if closed window was passed' do other_window = (@session.windows - [@window]).first @session.within_window other_window do other_window.close end expect do @session.within_window(other_window) do raise 'should not be invoked' end end.to raise_error(@session.driver.no_such_window_error) expect(@session.current_window).to eq(@window) expect(@session).to have_css('#doesNotOpenWindows') expect(@session.send(:scopes)).to eq([nil]) end end context "with lambda" do it "should find the div in another window" do @session.within_window(->{ @session.title == 'Title of the first popup'}) do expect(@session).to have_css('#divInPopupOne') end end it "should find divs in both windows" do @session.within_window(->{ @session.title == 'Title of popup two'}) do expect(@session).to have_css('#divInPopupTwo') end @session.within_window(->{ @session.title == 'Title of the first popup'}) do expect(@session).to have_css('#divInPopupOne') end expect(@session.title).to eq('With Windows') end it "should raise error if window wasn't found" do expect do @session.within_window(->{ @session.title == 'Invalid title'}) do expect(@session).to have_css('#divInPopupOne') end end.to raise_error(Capybara::WindowError, "Could not find a window matching block/lambda") expect(@session.current_window).to eq(@window) expect(@session).to have_css('#doesNotOpenWindows') expect(@session.send(:scopes)).to eq([nil]) end it "returns value from the block" do value = @session.within_window(->{ @session.title == 'Title of popup two'}) do 42 end expect(value).to eq(42) end it "should switch back if exception was raised inside block" do expect do @session.within_window(->{ @session.title == 'Title of popup two'}) do raise 'some error' end end.to raise_error(StandardError, 'some error') expect(@session.current_window).to eq(@window) expect(@session.send(:scopes)).to eq([nil]) end end context "with string" do it "should warn" do expect(@session).to receive(:warn).with("DEPRECATION WARNING: Passing string argument "\ "to #within_window is deprecated. Pass window object or lambda. "\ "(called from #{__FILE__}:138)").and_call_original @session.within_window('firstPopup') {} end it "should find window by handle" do window = (@session.windows - [@window]).first @session.within_window window.handle do expect(['Title of the first popup', 'Title of popup two']).to include(@session.title) end end it "should find the div in firstPopup" do @session.within_window("firstPopup") do expect(@session.find("//*[@id='divInPopupOne']").text).to eq 'This is the text of divInPopupOne' end end it "should find the div in secondPopup" do @session.within_window("secondPopup") do expect(@session.find("//*[@id='divInPopupTwo']").text).to eq 'This is the text of divInPopupTwo' end end it "should find the divs in both popups" do @session.within_window("secondPopup") do expect(@session.find("//*[@id='divInPopupTwo']").text).to eq 'This is the text of divInPopupTwo' end @session.within_window("firstPopup") do expect(@session.find("//*[@id='divInPopupOne']").text).to eq 'This is the text of divInPopupOne' end end it "should find the div in the main window after finding a div in a popup" do @session.within_window("secondPopup") do expect(@session.find("//*[@id='divInPopupTwo']").text).to eq 'This is the text of divInPopupTwo' end expect(@session.find("//*[@id='doesNotOpenWindows']").text).to eq 'Does not open windows' end it "should reset scope when switching windows" do @session.within(:css, '#doesNotOpenWindows') do @session.within_window("secondPopup") do expect(@session.find("//*[@id='divInPopupTwo']").text).to eq 'This is the text of divInPopupTwo' end end end it "should switch back if exception was raised inside block" do expect do @session.within_window('secondPopup') do raise 'some error' end end.to raise_error(StandardError, 'some error') expect(@session.current_window).to eq(@window) end end end capybara-2.5.0/lib/capybara/spec/session/window/windows_spec.rb0000644000175000017500000000170412573712570023644 0ustar lunarlunarCapybara::SpecHelper.spec '#windows', requires: [:windows] do before(:each) do @window = @session.current_window @session.visit('/with_windows') @session.find(:css, '#openTwoWindows').click @session.document.synchronize(3, errors: [Capybara::CapybaraError]) do raise Capybara::CapybaraError if @session.windows.size != 3 end end after(:each) do (@session.windows - [@window]).each do |w| @session.switch_to_window w w.close end @session.switch_to_window(@window) end it 'should return objects of Capybara::Window class' do expect(@session.windows.map { |window| window.instance_of?(Capybara::Window) }).to eq([true] * 3) end it 'should switchable windows' do titles = @session.windows.map do |window| @session.within_window(window) { @session.title } end expect(titles).to match_array([ 'With Windows', 'Title of the first popup', 'Title of popup two' ]) end end capybara-2.5.0/lib/capybara/spec/session/window/become_closed_spec.rb0000644000175000017500000000600512573712570024734 0ustar lunarlunarCapybara::SpecHelper.spec '#become_closed', requires: [:windows, :js] do before(:each) do @window = @session.current_window @session.visit('/with_windows') @other_window = @session.window_opened_by do @session.find(:css, '#openWindow').click end end after(:each) do @session.document.synchronize(5, errors: [Capybara::CapybaraError]) do raise Capybara::CapybaraError if @session.windows.size != 1 end @session.switch_to_window(@window) end context 'with :wait option' do it 'should wait if value of :wait is more than timeout' do @session.within_window @other_window do @session.execute_script('setTimeout(function(){ window.close(); }, 500);') end Capybara.using_wait_time 0.1 do expect(@other_window).to become_closed(wait: 2) end end it 'should raise error if value of :wait is less than timeout' do @session.within_window @other_window do @session.execute_script('setTimeout(function(){ window.close(); }, 700);') end Capybara.using_wait_time 2 do expect do expect(@other_window).to become_closed(wait: 0.4) end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\Aexpected # to become closed after 0.4 seconds\Z/) end end end context 'without :wait option' do it 'should wait if value of default_max_wait_time is more than timeout' do @session.within_window @other_window do @session.execute_script('setTimeout(function(){ window.close(); }, 500);') end Capybara.using_wait_time 1.5 do expect(@other_window).to become_closed end end it 'should raise error if value of default_max_wait_time is less than timeout' do @session.within_window @other_window do @session.execute_script('setTimeout(function(){ window.close(); }, 900);') end Capybara.using_wait_time 0.4 do expect do expect(@other_window).to become_closed end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\Aexpected # to become closed after 0.4 seconds\Z/) end end end context 'with not_to' do it 'should raise error if default_max_wait_time is more than timeout' do @session.within_window @other_window do @session.execute_script('setTimeout(function(){ window.close(); }, 700);') end Capybara.using_wait_time 0.4 do expect do expect(@other_window).not_to become_closed end end end it 'should raise error if default_max_wait_time is more than timeout' do @session.within_window @other_window do @session.execute_script('setTimeout(function(){ window.close(); }, 700);') end Capybara.using_wait_time 1.1 do expect do expect(@other_window).not_to become_closed end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\Aexpected # not to become closed after 1.1 seconds\Z/) end end end end capybara-2.5.0/lib/capybara/spec/session/window/window_spec.rb0000644000175000017500000001450212573712570023461 0ustar lunarlunarCapybara::SpecHelper.spec Capybara::Window, requires: [:windows] do before(:each) do @window = @session.current_window @session.visit('/with_windows') end after(:each) do (@session.windows - [@window]).each do |w| @session.switch_to_window w w.close end @session.switch_to_window(@window) end describe '#exists?' do before(:each) do @other_window = @session.window_opened_by do @session.find(:css, '#openWindow').click end end it "should become false after window was closed" do expect do @session.switch_to_window @other_window @other_window.close end.to change { @other_window.exists? }.from(true).to(false) end end describe '#closed?' do it "should become true after window was closed" do @other_window = @session.window_opened_by do @session.find(:css, '#openWindow').click end expect do @session.switch_to_window @other_window @other_window.close end.to change { @other_window.closed? }.from(false).to(true) end end describe '#current?' do before(:each) do @other_window = @session.window_opened_by do @session.find(:css, '#openWindow').click end end it 'should become true after switching to window' do expect do @session.switch_to_window(@other_window) end.to change { @other_window.current? }.from(false).to(true) end it 'should return false if window is closed' do @session.switch_to_window(@other_window) @other_window.close expect(@other_window.current?).to eq(false) end end describe '#close' do before(:each) do @other_window = @session.window_opened_by do @session.find(:css, '#openWindow').click end end it 'should switch to original window if invoked not for current window' do expect(@session.windows.size).to eq(2) expect(@session.current_window).to eq(@window) @other_window.close expect(@session.windows.size).to eq(1) expect(@session.current_window).to eq(@window) end it 'should make subsequent invocations of other methods raise no_such_window_error if invoked for current window' do @session.switch_to_window(@other_window) expect(@session.current_window).to eq(@other_window) @other_window.close expect do @session.find(:css, '#some_id') end.to raise_error(@session.driver.no_such_window_error) @session.switch_to_window(@window) end end describe '#size' do it 'should return size of whole window', requires: [:windows, :js] do skip "Chromedriver returns a size larger than outerWidth, outerHeight???" if ENV['TRAVIS'] && @session.respond_to?(:mode) && (@session.mode == :selenium_chrome) expect(@session.current_window.size).to eq @session.evaluate_script("[window.outerWidth, window.outerHeight];") end it 'should switch to original window if invoked not for current window' do skip "Chromedriver returns a size larger than outerWidth, outerHeight???" if ENV['TRAVIS'] && @session.respond_to?(:mode) && (@session.mode == :selenium_chrome) @other_window = @session.window_opened_by do @session.find(:css, '#openWindow').click end size = @session.within_window @other_window do @session.evaluate_script("[window.outerWidth, window.outerHeight];") end expect(@other_window.size).to eq(size) expect(@session.current_window).to eq(@window) end end describe '#resize_to' do it 'should be able to resize window', requires: [:windows, :js] do width, height = @session.evaluate_script("[window.outerWidth, window.outerHeight];") @session.current_window.resize_to(width-10, height-10) expect(@session.evaluate_script("[window.outerWidth, window.outerHeight];")).to eq([width-10, height-10]) end it 'should stay on current window if invoked not for current window', requires: [:windows, :js] do @other_window = @session.window_opened_by do @session.find(:css, '#openWindow').click end @other_window.resize_to(400, 300) expect(@session.current_window).to eq(@window) # #size returns values larger than availWidth, availHeight with Chromedriver # expect(@other_window.size).to eq([400, 300]) @session.within_window(@other_window) do expect(@session.evaluate_script("[window.outerWidth, window.outerHeight]")).to eq([400,300]) end end end describe '#maximize' do it 'should be able to maximize window', requires: [:windows, :js] do skip "This test fails when run with Firefox on Travis - see issue #1493 - skipping for now" if ENV['TRAVIS'] && @session.respond_to?(:mode) && (@session.mode == :selenium_focus) screen_width, screen_height = @session.evaluate_script("[window.screen.availWidth, window.screen.availHeight];") window = @session.current_window window.resize_to(screen_width-100, screen_height-100) expect(@session.evaluate_script("[window.outerWidth, window.outerHeight];")).to eq([screen_width-100, screen_height-100]) window.maximize sleep 0.5 # The timing on maximize is finicky on Travis -- wait a bit for maximize to occur expect(@session.evaluate_script("[window.outerWidth, window.outerHeight];")).to eq([screen_width, screen_height]) end it 'should stay on current window if invoked not for current window', requires: [:windows, :js] do skip "This test fails when run with Firefox on Travis - see issue #1493 - skipping for now" if ENV['TRAVIS'] && @session.respond_to?(:mode) && (@session.mode == :selenium_focus) @other_window = @session.window_opened_by do @session.find(:css, '#openWindow').click end @other_window.maximize sleep 0.5 # The timing on maximize is finicky on Travis -- wait a bit for maximize to occur expect(@session.current_window).to eq(@window) # #size returns values larger than availWidth, availHeight with Chromedriver # expect(@other_window.size).to eq(@session.evaluate_script("[window.screen.availWidth, window.screen.availHeight];")) @session.within_window(@other_window) do expect(@session.evaluate_script("[window.outerWidth, window.outerHeight]")).to eq(@session.evaluate_script("[window.screen.availWidth, window.screen.availHeight];")) end end end end capybara-2.5.0/lib/capybara/spec/session/response_code.rb0000644000175000017500000000031612573712570022457 0ustar lunarlunarCapybara::SpecHelper.spec '#status_code' do it "should return response codes", :requires => [:status_code] do @session.visit('/with_simple_html') expect(@session.status_code).to eq(200) end end capybara-2.5.0/lib/capybara/spec/session/dismiss_prompt_spec.rb0000644000175000017500000000101112573712570023706 0ustar lunarlunarCapybara::SpecHelper.spec '#dismiss_prompt', :requires => [:modals] do before do @session.visit('/with_js') end it "should dismiss the prompt" do @session.dismiss_prompt do @session.click_link('Open prompt') end expect(@session).to have_xpath("//a[@id='open-prompt' and @response='dismissed']") end it "should return the message presented" do message = @session.dismiss_prompt do @session.click_link('Open prompt') end expect(message).to eq('Prompt opened') end endcapybara-2.5.0/lib/capybara/spec/session/find_by_id_spec.rb0000644000175000017500000000157712573712570022741 0ustar lunarlunarCapybara::SpecHelper.spec '#find_by_id' do before do @session.visit('/with_html') end it "should find any element by id" do expect(@session.find_by_id('red').tag_name).to eq('a') end it "casts to string" do expect(@session.find_by_id(:'red').tag_name).to eq('a') end it "should raise error if no element with id is found" do expect do @session.find_by_id('nothing_with_this_id') end.to raise_error(Capybara::ElementNotFound) end context "with :visible option" do it "finds invisible elements when `false`" do expect(@session.find_by_id("hidden_via_ancestor", :visible => false).text(:all)).to match(/with hidden ancestor/) end it "finds invisible elements when `false`" do expect do @session.find_by_id("hidden_via_ancestor", :visible => true) end.to raise_error(Capybara::ElementNotFound) end end end capybara-2.5.0/lib/capybara/spec/session/text_spec.rb0000644000175000017500000000413112573712570021624 0ustar lunarlunarCapybara::SpecHelper.spec '#text' do it "should print the text of the page" do @session.visit('/with_simple_html') expect(@session.text).to eq('Bar') end it "ignores invisible text by default" do @session.visit('/with_html') expect(@session.find(:id, "hidden-text").text).to eq('Some of this text is') end it "shows invisible text if `:all` given" do @session.visit('/with_html') expect(@session.find(:id, "hidden-text").text(:all)).to eq('Some of this text is hidden!') end it "ignores invisible text if `:visible` given" do Capybara.ignore_hidden_elements = false @session.visit('/with_html') expect(@session.find(:id, "hidden-text").text(:visible)).to eq('Some of this text is') end it "ignores invisible text if `Capybara.ignore_hidden_elements = true`" do @session.visit('/with_html') expect(@session.find(:id, "hidden-text").text).to eq('Some of this text is') Capybara.ignore_hidden_elements = false expect(@session.find(:id, "hidden-text").text).to eq('Some of this text is hidden!') end it "ignores invisible text if `Capybara.visible_text_only = true`" do @session.visit('/with_html') Capybara.visible_text_only = true expect(@session.find(:id, "hidden-text").text).to eq('Some of this text is') Capybara.ignore_hidden_elements = false expect(@session.find(:id, "hidden-text").text).to eq('Some of this text is') end it "ignores invisible text if ancestor is invisible" do @session.visit('/with_html') expect(@session.find(:id, "hidden_via_ancestor", visible: false).text).to eq('') end context "with css as default selector" do before { Capybara.default_selector = :css } it "should print the text of the page" do @session.visit('/with_simple_html') expect(@session.text).to eq('Bar') end after { Capybara.default_selector = :xpath } end it "should strip whitespace" do @session.visit('/with_html') n = @session.find(:css, '#second') expect(@session.find(:css, '#second').text).to match \ /\ADuis aute .* text with whitespace .* est laborum\.\z/ end end capybara-2.5.0/lib/capybara/spec/session/find_field_spec.rb0000644000175000017500000000510612573712570022726 0ustar lunarlunarCapybara::SpecHelper.spec '#find_field' do before do @session.visit('/form') end it "should find any field" do expect(@session.find_field('Dog').value).to eq('dog') expect(@session.find_field('form_description').text).to eq('Descriptive text goes here') expect(@session.find_field('Region')[:name]).to eq('form[region]') end it "casts to string" do expect(@session.find_field(:'Dog').value).to eq('dog') end it "should raise error if the field doesn't exist" do expect do @session.find_field('Does not exist') end.to raise_error(Capybara::ElementNotFound) end it "should warn if filter option is invalid" do expect_any_instance_of(Kernel).to receive(:warn). with('Invalid value nil passed to filter disabled') @session.find_field('Dog', disabled: nil) end it "should be aliased as 'field_labeled' for webrat compatibility" do expect(@session.field_labeled('Dog').value).to eq('dog') expect do @session.field_labeled('Does not exist') end.to raise_error(Capybara::ElementNotFound) end context "with :exact option" do it "should accept partial matches when false" do expect(@session.find_field("Explanation", :exact => false)[:name]).to eq("form[name_explanation]") end it "should not accept partial matches when true" do expect do @session.find_field("Explanation", :exact => true) end.to raise_error(Capybara::ElementNotFound) end end context "with :disabled option" do it "should find disabled fields when true" do expect(@session.find_field("Disabled Checkbox", :disabled => true)[:name]).to eq("form[disabled_checkbox]") end it "should not find disabled fields when false" do expect do @session.find_field("Disabled Checkbox", :disabled => false) end.to raise_error(Capybara::ElementNotFound) end it "should not find disabled fields by default" do expect do @session.find_field("Disabled Checkbox") end.to raise_error(Capybara::ElementNotFound) end end context 'with :readonly option' do it "should find readonly fields when true" do expect(@session.find_field('form[readonly_test]', readonly: true)[:id]).to eq 'readonly' end it "should not find readonly fields when false" do expect(@session.find_field('form[readonly_test]', readonly: false)[:id]).to eq 'not_readonly' end it "should ignore readonly by default" do expect do @session.find_field('form[readonly_test]') end.to raise_error(Capybara::Ambiguous, /found 2 elements/) end end end capybara-2.5.0/lib/capybara/spec/session/assert_selector.rb0000644000175000017500000001462012573712570023033 0ustar lunarlunarCapybara::SpecHelper.spec '#assert_selector' do before do @session.visit('/with_html') end it "should be true if the given selector is on the page" do @session.assert_selector(:xpath, "//p") @session.assert_selector(:css, "p a#foo") @session.assert_selector("//p[contains(.,'est')]") end it "should be false if the given selector is not on the page" do expect { @session.assert_selector(:xpath, "//abbr") }.to raise_error(Capybara::ElementNotFound) expect { @session.assert_selector(:css, "p a#doesnotexist") }.to raise_error(Capybara::ElementNotFound) expect { @session.assert_selector("//p[contains(.,'thisstringisnotonpage')]") }.to raise_error(Capybara::ElementNotFound) end it "should use default selector" do Capybara.default_selector = :css expect { @session.assert_selector("p a#doesnotexist") }.to raise_error(Capybara::ElementNotFound) @session.assert_selector("p a#foo") end it "should respect scopes" do @session.within "//p[@id='first']" do @session.assert_selector(".//a[@id='foo']") expect { @session.assert_selector(".//a[@id='red']") }.to raise_error(Capybara::ElementNotFound) end end context "with count" do it "should be true if the content is on the page the given number of times" do @session.assert_selector("//p", :count => 3) @session.assert_selector("//p//a[@id='foo']", :count => 1) @session.assert_selector("//p[contains(.,'est')]", :count => 1) end it "should be false if the content is on the page the given number of times" do expect { @session.assert_selector("//p", :count => 6) }.to raise_error(Capybara::ElementNotFound) expect { @session.assert_selector("//p//a[@id='foo']", :count => 2) }.to raise_error(Capybara::ElementNotFound) expect { @session.assert_selector("//p[contains(.,'est')]", :count => 5) }.to raise_error(Capybara::ElementNotFound) end it "should be false if the content isn't on the page at all" do expect { @session.assert_selector("//abbr", :count => 2) }.to raise_error(Capybara::ElementNotFound) expect { @session.assert_selector("//p//a[@id='doesnotexist']", :count => 1) }.to raise_error(Capybara::ElementNotFound) end end context "with text" do it "should discard all matches where the given string is not contained" do @session.assert_selector("//p//a", :text => "Redirect", :count => 1) expect { @session.assert_selector("//p", :text => "Doesnotexist") }.to raise_error(Capybara::ElementNotFound) end it "should discard all matches where the given regexp is not matched" do @session.assert_selector("//p//a", :text => /re[dab]i/i, :count => 1) expect { @session.assert_selector("//p//a", :text => /Red$/) }.to raise_error(Capybara::ElementNotFound) end end context "with wait", :requires => [:js] do it "should find element if it appears before given wait duration" do Capybara.using_wait_time(0.1) do @session.visit('/with_js') @session.click_link('Click me') @session.assert_selector(:css, "a#has-been-clicked", :text => "Has been clicked", :wait => 0.9) end end end end Capybara::SpecHelper.spec '#refute_selector' do it "should be an alias of #assert_no_selector" do expect(Capybara::Node::Matchers.instance_method(:refute_selector)).to eq Capybara::Node::Matchers.instance_method(:assert_no_selector) end end Capybara::SpecHelper.spec '#assert_no_selector' do before do @session.visit('/with_html') end it "should be false if the given selector is on the page" do expect { @session.assert_no_selector(:xpath, "//p") }.to raise_error(Capybara::ElementNotFound) expect { @session.assert_no_selector(:css, "p a#foo") }.to raise_error(Capybara::ElementNotFound) expect { @session.assert_no_selector("//p[contains(.,'est')]") }.to raise_error(Capybara::ElementNotFound) end it "should be true if the given selector is not on the page" do @session.assert_no_selector(:xpath, "//abbr") @session.assert_no_selector(:css, "p a#doesnotexist") @session.assert_no_selector("//p[contains(.,'thisstringisnotonpage')]") end it "should use default selector" do Capybara.default_selector = :css @session.assert_no_selector("p a#doesnotexist") expect { @session.assert_no_selector("p a#foo") }.to raise_error(Capybara::ElementNotFound) end it "should respect scopes" do @session.within "//p[@id='first']" do expect { @session.assert_no_selector(".//a[@id='foo']") }.to raise_error(Capybara::ElementNotFound) @session.assert_no_selector(".//a[@id='red']") end end context "with count" do it "should be false if the content is on the page the given number of times" do expect { @session.assert_no_selector("//p", :count => 3) }.to raise_error(Capybara::ElementNotFound) expect { @session.assert_no_selector("//p//a[@id='foo']", :count => 1) }.to raise_error(Capybara::ElementNotFound) expect { @session.assert_no_selector("//p[contains(.,'est')]", :count => 1) }.to raise_error(Capybara::ElementNotFound) end it "should be true if the content is on the page the wrong number of times" do @session.assert_no_selector("//p", :count => 6) @session.assert_no_selector("//p//a[@id='foo']", :count => 2) @session.assert_no_selector("//p[contains(.,'est')]", :count => 5) end it "should be true if the content isn't on the page at all" do @session.assert_no_selector("//abbr", :count => 2) @session.assert_no_selector("//p//a[@id='doesnotexist']", :count => 1) end end context "with text" do it "should discard all matches where the given string is contained" do expect { @session.assert_no_selector("//p//a", :text => "Redirect", :count => 1) }.to raise_error(Capybara::ElementNotFound) @session.assert_no_selector("//p", :text => "Doesnotexist") end it "should discard all matches where the given regexp is matched" do expect { @session.assert_no_selector("//p//a", :text => /re[dab]i/i, :count => 1) }.to raise_error(Capybara::ElementNotFound) @session.assert_no_selector("//p//a", :text => /Red$/) end end context "with wait", :requires => [:js] do it "should not find element if it appears after given wait duration" do @session.visit('/with_js') @session.click_link('Click me') @session.assert_no_selector(:css, "a#has-been-clicked", :text => "Has been clicked", :wait => 0.1) end end end capybara-2.5.0/lib/capybara/spec/session/within_frame_spec.rb0000644000175000017500000000415012573712570023315 0ustar lunarlunarCapybara::SpecHelper.spec '#within_frame', :requires => [:frames] do before(:each) do @session.visit('/within_frames') end it "should find the div in frameOne" do @session.within_frame("frameOne") do expect(@session.find("//*[@id='divInFrameOne']").text).to eql 'This is the text of divInFrameOne' end end it "should find the div in FrameTwo" do @session.within_frame("frameTwo") do expect(@session.find("//*[@id='divInFrameTwo']").text).to eql 'This is the text of divInFrameTwo' end end it "should find the text div in the main window after finding text in frameOne" do @session.within_frame("frameOne") do expect(@session.find("//*[@id='divInFrameOne']").text).to eql 'This is the text of divInFrameOne' end expect(@session.find("//*[@id='divInMainWindow']").text).to eql 'This is the text for divInMainWindow' end it "should find the text div in the main window after finding text in frameTwo" do @session.within_frame("frameTwo") do expect(@session.find("//*[@id='divInFrameTwo']").text).to eql 'This is the text of divInFrameTwo' end expect(@session.find("//*[@id='divInMainWindow']").text).to eql 'This is the text for divInMainWindow' end it "should return the result of executing the block" do expect(@session.within_frame("frameOne") { "return value" }).to eql "return value" end it "should find the div given Element" do element = @session.find(:id, 'frameOne') @session.within_frame element do expect(@session.find("//*[@id='divInFrameOne']").text).to eql 'This is the text of divInFrameOne' end end it "should find multiple nested frames" do @session.within_frame 'parentFrame' do @session.within_frame 'childFrame' do @session.within_frame 'grandchildFrame1' do end @session.within_frame 'grandchildFrame2' do end end end end it "should reset scope when changing frames" do @session.within(:css, '#divInMainWindow') do @session.within_frame 'parentFrame' do expect(@session.has_selector?(:css, "iframe#childFrame")).to be true end end end end capybara-2.5.0/lib/capybara/spec/session/within_spec.rb0000644000175000017500000001177212573712570022153 0ustar lunarlunarCapybara::SpecHelper.spec '#within' do before do @session.visit('/with_scope') end context "with CSS selector" do it "should click links in the given scope" do @session.within(:css, "#for_bar li", text: 'With Simple HTML') do @session.click_link('Go') end expect(@session).to have_content('Bar') end it "should assert content in the given scope" do @session.within(:css, "#for_foo") do expect(@session).not_to have_content('First Name') end expect(@session).to have_content('First Name') end it "should accept additional options" do @session.within(:css, "#for_bar li", :text => 'With Simple HTML') do @session.click_link('Go') end expect(@session).to have_content('Bar') end end context "with XPath selector" do it "should click links in the given scope" do @session.within(:xpath, "//div[@id='for_bar']//li[contains(.,'With Simple HTML')]") do @session.click_link('Go') end expect(@session).to have_content('Bar') end end context "with the default selector" do it "should use XPath" do @session.within("//div[@id='for_bar']//li[contains(.,'With Simple HTML')]") do @session.click_link('Go') end expect(@session).to have_content('Bar') end end context "with Node rather than selector" do it "should click links in the given scope" do node_of_interest = @session.find(:css, "#for_bar li", text: 'With Simple HTML') @session.within(node_of_interest) do @session.click_link('Go') end expect(@session).to have_content('Bar') end end context "with the default selector set to CSS" do before { Capybara.default_selector = :css } it "should use CSS" do @session.within("#for_bar li", text: 'With Simple HTML') do @session.click_link('Go') end expect(@session).to have_content('Bar') end after { Capybara.default_selector = :xpath } end context "with nested scopes" do it "should respect the inner scope" do @session.within("//div[@id='for_bar']") do @session.within(".//li[contains(.,'Bar')]") do @session.click_link('Go') end end expect(@session).to have_content('Another World') end it "should respect the outer scope" do @session.within("//div[@id='another_foo']") do @session.within(".//li[contains(.,'With Simple HTML')]") do @session.click_link('Go') end end expect(@session).to have_content('Hello world') end end it "should raise an error if the scope is not found on the page" do expect do @session.within("//div[@id='doesnotexist']") do end end.to raise_error(Capybara::ElementNotFound) end it "should restore the scope when an error is raised" do expect do @session.within("//div[@id='for_bar']") do expect do expect do @session.within(".//div[@id='doesnotexist']") do end end.to raise_error(Capybara::ElementNotFound) end.to_not change { @session.has_xpath?(".//div[@id='another_foo']") }.from(false) end end.to_not change { @session.has_xpath?(".//div[@id='another_foo']") }.from(true) end it "should fill in a field and click a button" do @session.within("//li[contains(.,'Bar')]") do @session.click_button('Go') end expect(extract_results(@session)['first_name']).to eq('Peter') @session.visit('/with_scope') @session.within("//li[contains(.,'Bar')]") do @session.fill_in('First Name', :with => 'Dagobert') @session.click_button('Go') end expect(extract_results(@session)['first_name']).to eq('Dagobert') end end Capybara::SpecHelper.spec '#within_fieldset' do before do @session.visit('/fieldsets') end it "should restrict scope to a fieldset given by id" do @session.within_fieldset("villain_fieldset") do @session.fill_in("Name", :with => 'Goldfinger') @session.click_button("Create") end expect(extract_results(@session)['villain_name']).to eq('Goldfinger') end it "should restrict scope to a fieldset given by legend" do @session.within_fieldset("Villain") do @session.fill_in("Name", :with => 'Goldfinger') @session.click_button("Create") end expect(extract_results(@session)['villain_name']).to eq('Goldfinger') end end Capybara::SpecHelper.spec '#within_table' do before do @session.visit('/tables') end it "should restrict scope to a fieldset given by id" do @session.within_table("girl_table") do @session.fill_in("Name", :with => 'Christmas') @session.click_button("Create") end expect(extract_results(@session)['girl_name']).to eq('Christmas') end it "should restrict scope to a fieldset given by legend" do @session.within_table("Villain") do @session.fill_in("Name", :with => 'Quantum') @session.click_button("Create") end expect(extract_results(@session)['villain_name']).to eq('Quantum') end end capybara-2.5.0/lib/capybara/spec/session/click_link_spec.rb0000644000175000017500000001320212573712570022741 0ustar lunarlunarCapybara::SpecHelper.spec '#click_link' do before do @session.visit('/with_html') end it "should wait for asynchronous load", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') @session.click_link('Has been clicked') end it "casts to string" do @session.click_link(:'foo') expect(@session).to have_content('Another World') end it "raises any errors caught inside the server", :requires => [:server] do quietly { @session.visit("/error") } expect do @session.click_link('foo') end.to raise_error(TestApp::TestAppError) end context "with id given" do it "should take user to the linked page" do @session.click_link('foo') expect(@session).to have_content('Another World') end end context "with text given" do it "should take user to the linked page" do @session.click_link('labore') expect(@session).to have_content('Bar') end it "should accept partial matches" do @session.click_link('abo') expect(@session).to have_content('Bar') end end context "with title given" do it "should take user to the linked page" do @session.click_link('awesome title') expect(@session).to have_content('Bar') end it "should accept partial matches" do @session.click_link('some titl') expect(@session).to have_content('Bar') end end context "with alternative text given to a contained image" do it "should take user to the linked page" do @session.click_link('awesome image') expect(@session).to have_content('Bar') end it "should accept partial matches" do @session.click_link('some imag') expect(@session).to have_content('Bar') end end context "with a locator that doesn't exist" do it "should raise an error" do msg = "Unable to find link \"does not exist\"" expect do @session.click_link('does not exist') end.to raise_error(Capybara::ElementNotFound, msg) end end context "with :href option given" do it "should find links with valid href" do @session.click_link('labore', :href => '/with_simple_html') expect(@session).to have_content('Bar') end it "should raise error if link wasn't found" do expect { @session.click_link('labore', :href => 'invalid_href') }.to raise_error(Capybara::ElementNotFound) end end context "with a regex :href option given" do it "should find a link matching an all-matching regex pattern" do @session.click_link('labore', :href => /.+/) expect(@session).to have_content('Bar') end it "should find a link matching an exact regex pattern" do @session.click_link('labore', :href => /\/with_simple_html/) expect(@session).to have_content('Bar') end it "should find a link matching a partial regex pattern" do @session.click_link('labore', :href => /\/with_simple/) expect(@session).to have_content('Bar') end it "should raise an error if no link's href matched the pattern" do expect { @session.click_link('labore', :href => /invalid_pattern/) }.to raise_error(Capybara::ElementNotFound) expect { @session.click_link('labore', :href => /.+d+/) }.to raise_error(Capybara::ElementNotFound) end end it "should follow relative links" do @session.visit('/') @session.click_link('Relative') expect(@session).to have_content('This is a test') end it "should follow protocol relative links" do @session.click_link('Protocol') expect(@session).to have_content('Another World') end it "should follow redirects" do @session.click_link('Redirect') expect(@session).to have_content('You landed') end it "should follow redirects back to itself" do @session.click_link('BackToMyself') expect(@session).to have_css('#referrer', text: /\/with_html$/) expect(@session).to have_content('This is a test') end it "should add query string to current URL with naked query string" do @session.click_link('Naked Query String') expect(@session).to have_content('Query String sent') end it "should do nothing on anchor links" do @session.fill_in("test_field", :with => 'blah') @session.click_link('Normal Anchor') expect(@session.find_field("test_field").value).to eq('blah') @session.click_link('Blank Anchor') expect(@session.find_field("test_field").value).to eq('blah') @session.click_link('Blank JS Anchor') expect(@session.find_field("test_field").value).to eq('blah') end it "should do nothing on URL+anchor links for the same page" do @session.fill_in("test_field", :with => 'blah') @session.click_link('Anchor on same page') expect(@session.find_field("test_field").value).to eq('blah') end it "should follow link on URL+anchor links for a different page" do @session.click_link('Anchor on different page') expect(@session).to have_content('Bar') end it "should follow link on anchor if the path has regex special characters" do @session.visit('/with.*html') @session.click_link('Anchor on different page') expect(@session).to have_content('Bar') end it "raise an error with links with no href" do expect do @session.click_link('No Href') end.to raise_error(Capybara::ElementNotFound) end context "with :exact option" do it "should accept partial matches when false" do @session.click_link('abo', :exact => false) expect(@session).to have_content('Bar') end it "should not accept partial matches when true" do expect do @session.click_link('abo', :exact => true) end.to raise_error(Capybara::ElementNotFound) end end end capybara-2.5.0/lib/capybara/spec/session/go_back_spec.rb0000644000175000017500000000056712573712570022236 0ustar lunarlunarCapybara::SpecHelper.spec '#go_back', :requires => [:js] do it "should fetch a response from the driver from the previous page" do @session.visit('/') expect(@session).to have_content('Hello world!') @session.visit('/foo') expect(@session).to have_content('Another World') @session.go_back expect(@session).to have_content('Hello world!') end end capybara-2.5.0/lib/capybara/spec/session/save_page_spec.rb0000644000175000017500000000534512573712570022602 0ustar lunarlunarCapybara::SpecHelper.spec '#save_page' do let(:alternative_path) { File.join(Dir.pwd, "save_and_open_page_tmp") } before do @session.visit("/foo") end after do Capybara.save_and_open_page_path = nil Dir.glob("capybara-*.html").each do |file| FileUtils.rm(file) end FileUtils.rm_rf alternative_path end it "saves the page in the root directory" do @session.save_page path = Dir.glob("capybara-*.html").first expect(File.read(path)).to include("Another World") end it "generates a sensible filename" do @session.save_page filename = Dir.glob("capybara-*.html").first expect(filename).to match(/^capybara-\d+\.html$/) end it "can store files in a specified directory" do Capybara.save_and_open_page_path = alternative_path @session.save_page path = Dir.glob(alternative_path + "/capybara-*.html").first expect(File.read(path)).to include("Another World") end it "uses the given filename" do @session.save_page("capybara-001122.html") expect(File.read("capybara-001122.html")).to include("Another World") end it "returns an absolute path in pwd" do result = @session.save_page path = File.expand_path(Dir.glob("capybara-*.html").first, Dir.pwd) expect(result).to eq(path) end it "returns an absolute path in given directory" do Capybara.save_and_open_page_path = alternative_path result = @session.save_page path = File.expand_path(Dir.glob(alternative_path + "/capybara-*.html").first, alternative_path) expect(result).to eq(path) end context "asset_host contains a string" do before { Capybara.asset_host = "http://example.com" } after { Capybara.asset_host = nil } it "prepends base tag with value from asset_host to the head" do @session.visit("/with_js") path = @session.save_page result = File.read(path) expect(result).to include("") end it "doesn't prepend base tag to pages when asset_host is nil" do Capybara.asset_host = nil @session.visit("/with_js") path = @session.save_page result = File.read(path) expect(result).to include('" do @session.visit("/with_simple_html") path = @session.save_page result = File.read(path) expect(result).to include("Bar") end end end capybara-2.5.0/lib/capybara/spec/session/has_selector_spec.rb0000644000175000017500000001267212573712570023324 0ustar lunarlunarCapybara::SpecHelper.spec '#has_selector?' do before do @session.visit('/with_html') end it "should be true if the given selector is on the page" do expect(@session).to have_selector(:xpath, "//p") expect(@session).to have_selector(:css, "p a#foo") expect(@session).to have_selector("//p[contains(.,'est')]") end it "should be false if the given selector is not on the page" do expect(@session).not_to have_selector(:xpath, "//abbr") expect(@session).not_to have_selector(:css, "p a#doesnotexist") expect(@session).not_to have_selector("//p[contains(.,'thisstringisnotonpage')]") end it "should use default selector" do Capybara.default_selector = :css expect(@session).not_to have_selector("p a#doesnotexist") expect(@session).to have_selector("p a#foo") end it "should respect scopes" do @session.within "//p[@id='first']" do expect(@session).to have_selector(".//a[@id='foo']") expect(@session).not_to have_selector(".//a[@id='red']") end end context "with count" do it "should be true if the content is on the page the given number of times" do expect(@session).to have_selector("//p", :count => 3) expect(@session).to have_selector("//p//a[@id='foo']", :count => 1) expect(@session).to have_selector("//p[contains(.,'est')]", :count => 1) end it "should be false if the content is on the page the given number of times" do expect(@session).not_to have_selector("//p", :count => 6) expect(@session).not_to have_selector("//p//a[@id='foo']", :count => 2) expect(@session).not_to have_selector("//p[contains(.,'est')]", :count => 5) end it "should be false if the content isn't on the page at all" do expect(@session).not_to have_selector("//abbr", :count => 2) expect(@session).not_to have_selector("//p//a[@id='doesnotexist']", :count => 1) end end context "with text" do it "should discard all matches where the given string is not contained" do expect(@session).to have_selector("//p//a", :text => "Redirect", :count => 1) expect(@session).not_to have_selector("//p", :text => "Doesnotexist") end it "should respect visibility setting" do expect(@session).to have_selector(:id, "hidden-text", :text => "Some of this text is hidden!", :visible => false) expect(@session).not_to have_selector(:id, "hidden-text", :text => "Some of this text is hidden!", :visible => true) Capybara.ignore_hidden_elements = false expect(@session).to have_selector(:id, "hidden-text", :text => "Some of this text is hidden!", :visible => false) Capybara.visible_text_only = true expect(@session).not_to have_selector(:id, "hidden-text", :text => "Some of this text is hidden!", :visible => true) end it "should discard all matches where the given regexp is not matched" do expect(@session).to have_selector("//p//a", :text => /re[dab]i/i, :count => 1) expect(@session).not_to have_selector("//p//a", :text => /Red$/) end end end Capybara::SpecHelper.spec '#has_no_selector?' do before do @session.visit('/with_html') end it "should be false if the given selector is on the page" do expect(@session).not_to have_no_selector(:xpath, "//p") expect(@session).not_to have_no_selector(:css, "p a#foo") expect(@session).not_to have_no_selector("//p[contains(.,'est')]") end it "should be true if the given selector is not on the page" do expect(@session).to have_no_selector(:xpath, "//abbr") expect(@session).to have_no_selector(:css, "p a#doesnotexist") expect(@session).to have_no_selector("//p[contains(.,'thisstringisnotonpage')]") end it "should use default selector" do Capybara.default_selector = :css expect(@session).to have_no_selector("p a#doesnotexist") expect(@session).not_to have_no_selector("p a#foo") end it "should respect scopes" do @session.within "//p[@id='first']" do expect(@session).not_to have_no_selector(".//a[@id='foo']") expect(@session).to have_no_selector(".//a[@id='red']") end end context "with count" do it "should be false if the content is on the page the given number of times" do expect(@session).not_to have_no_selector("//p", :count => 3) expect(@session).not_to have_no_selector("//p//a[@id='foo']", :count => 1) expect(@session).not_to have_no_selector("//p[contains(.,'est')]", :count => 1) end it "should be true if the content is on the page the wrong number of times" do expect(@session).to have_no_selector("//p", :count => 6) expect(@session).to have_no_selector("//p//a[@id='foo']", :count => 2) expect(@session).to have_no_selector("//p[contains(.,'est')]", :count => 5) end it "should be true if the content isn't on the page at all" do expect(@session).to have_no_selector("//abbr", :count => 2) expect(@session).to have_no_selector("//p//a[@id='doesnotexist']", :count => 1) end end context "with text" do it "should discard all matches where the given string is contained" do expect(@session).not_to have_no_selector("//p//a", :text => "Redirect", :count => 1) expect(@session).to have_no_selector("//p", :text => "Doesnotexist") end it "should discard all matches where the given regexp is matched" do expect(@session).not_to have_no_selector("//p//a", :text => /re[dab]i/i, :count => 1) expect(@session).to have_no_selector("//p//a", :text => /Red$/) end end end capybara-2.5.0/lib/capybara/spec/session/has_button_spec.rb0000644000175000017500000000320612573712570023010 0ustar lunarlunarCapybara::SpecHelper.spec '#has_button?' do before do @session.visit('/form') end it "should be true if the given button is on the page" do expect(@session).to have_button('med') expect(@session).to have_button('crap321') expect(@session).to have_button(:'crap321') end it "should be true for disabled buttons if :disabled => true" do expect(@session).to have_button('Disabled button', :disabled => true) end it "should be false if the given button is not on the page" do expect(@session).not_to have_button('monkey') end it "should be false for disabled buttons by default" do expect(@session).not_to have_button('Disabled button') end it "should be false for disabled buttons if :disabled => false" do expect(@session).not_to have_button('Disabled button', :disabled => false) end end Capybara::SpecHelper.spec '#has_no_button?' do before do @session.visit('/form') end it "should be true if the given button is on the page" do expect(@session).not_to have_no_button('med') expect(@session).not_to have_no_button('crap321') end it "should be true for disabled buttons if :disabled => true" do expect(@session).not_to have_no_button('Disabled button', :disabled => true) end it "should be false if the given button is not on the page" do expect(@session).to have_no_button('monkey') end it "should be false for disabled buttons by default" do expect(@session).to have_no_button('Disabled button') end it "should be false for disabled buttons if :disabled => false" do expect(@session).to have_no_button('Disabled button', :disabled => false) end end capybara-2.5.0/lib/capybara/spec/session/has_title_spec.rb0000644000175000017500000000236212573712570022620 0ustar lunarlunarCapybara::SpecHelper.spec '#has_title?' do before do @session.visit('/with_js') end it "should be true if the page has the given title" do expect(@session).to have_title('with_js') end it "should allow regexp matches" do expect(@session).to have_title(/w[a-z]{3}_js/) expect(@session).not_to have_title(/monkey/) end it "should wait for title", :requires => [:js] do @session.click_link("Change title") expect(@session).to have_title("changed title") end it "should be false if the page has not the given title" do expect(@session).not_to have_title('monkey') end end Capybara::SpecHelper.spec '#has_no_title?' do before do @session.visit('/with_js') end it "should be false if the page has the given title" do expect(@session).not_to have_no_title('with_js') end it "should allow regexp matches" do expect(@session).not_to have_no_title(/w[a-z]{3}_js/) expect(@session).to have_no_title(/monkey/) end it "should wait for title to disappear", :requires => [:js] do @session.click_link("Change title") expect(@session).to have_no_title('with_js') end it "should be true if the page has not the given title" do expect(@session).to have_no_title('monkey') end end capybara-2.5.0/lib/capybara/spec/session/choose_spec.rb0000644000175000017500000000370312573712570022124 0ustar lunarlunarCapybara::SpecHelper.spec "#choose" do before do @session.visit('/form') end it "should choose a radio button by id" do @session.choose("gender_male") @session.click_button('awesome') expect(extract_results(@session)['gender']).to eq('male') end it "should choose a radio button by label" do @session.choose("Both") @session.click_button('awesome') expect(extract_results(@session)['gender']).to eq('both') end it "casts to string" do @session.choose("Both") @session.click_button(:'awesome') expect(extract_results(@session)['gender']).to eq('both') end context "with a locator that doesn't exist" do it "should raise an error" do msg = "Unable to find radio button \"does not exist\"" expect do @session.choose('does not exist') end.to raise_error(Capybara::ElementNotFound, msg) end end context "with a disabled radio button" do it "should raise an error" do expect do @session.choose('Disabled Radio') end.to raise_error(Capybara::ElementNotFound) end end context "with :exact option" do it "should accept partial matches when false" do @session.choose("Mal", :exact => false) @session.click_button('awesome') expect(extract_results(@session)['gender']).to eq('male') end it "should not accept partial matches when true" do expect do @session.choose("Mal", :exact => true) end.to raise_error(Capybara::ElementNotFound) end end context "with `option` option" do it "can check radio buttons by their value" do @session.choose('form[gender]', :option => "male") @session.click_button('awesome') expect(extract_results(@session)['gender']).to eq("male") end it "should raise an error if option not found" do expect do @session.choose('form[gender]', :option => "hermaphrodite") end.to raise_error(Capybara::ElementNotFound) end end end capybara-2.5.0/lib/capybara/spec/session/select_spec.rb0000644000175000017500000001525112573712570022124 0ustar lunarlunarCapybara::SpecHelper.spec "#select" do before do @session.visit('/form') end it "should return value of the first option" do expect(@session.find_field('Title').value).to eq('Mrs') end it "should return value of the selected option" do @session.select("Miss", :from => 'Title') expect(@session.find_field('Title').value).to eq('Miss') end it "should allow selecting options where there are inexact matches" do @session.select("Mr", :from => 'Title') expect(@session.find_field('Title').value).to eq('Mr') end it "should allow selecting options where they are the only inexact match" do @session.select("Mis", :from => 'Title') expect(@session.find_field('Title').value).to eq('Miss') end it "should not allow selecting options where they are the only inexact match if `Capybara.exact_options = true`" do Capybara.exact_options = true expect do @session.select("Mis", :from => 'Title') end.to raise_error(Capybara::ElementNotFound) end it "should not allow selecting an option if the match is ambiguous" do expect do @session.select("M", :from => 'Title') end.to raise_error(Capybara::Ambiguous) end it "should return the value attribute rather than content if present" do expect(@session.find_field('Locale').value).to eq('en') end it "should select an option from a select box by id" do @session.select("Finish", :from => 'form_locale') @session.click_button('awesome') expect(extract_results(@session)['locale']).to eq('fi') end it "should select an option from a select box by label" do @session.select("Finish", :from => 'Locale') @session.click_button('awesome') expect(extract_results(@session)['locale']).to eq('fi') end it "should select an option without giving a select box" do @session.select("Swedish") @session.click_button('awesome') expect(extract_results(@session)['locale']).to eq('sv') end it "should escape quotes" do @session.select("John's made-up language", :from => 'Locale') @session.click_button('awesome') expect(extract_results(@session)['locale']).to eq('jo') end it "should obey from" do @session.select("Miss", :from => "Other title") @session.click_button('awesome') results = extract_results(@session) expect(results['other_title']).to eq("Miss") expect(results['title']).not_to eq("Miss") end it "show match labels with preceding or trailing whitespace" do @session.select("Lojban", :from => 'Locale') @session.click_button('awesome') expect(extract_results(@session)['locale']).to eq('jbo') end it "casts to string" do @session.select(:"Miss", :from => :'Title') expect(@session.find_field('Title').value).to eq('Miss') end context "with a locator that doesn't exist" do it "should raise an error" do msg = "Unable to find select box \"does not exist\"" expect do @session.select('foo', :from => 'does not exist') end.to raise_error(Capybara::ElementNotFound, msg) end end context "with an option that doesn't exist" do it "should raise an error" do msg = "Unable to find option \"Does not Exist\"" expect do @session.select('Does not Exist', :from => 'form_locale') end.to raise_error(Capybara::ElementNotFound, msg) end end context "on a disabled select" do it "should raise an error" do expect do @session.select('Should not see me', :from => 'Disabled Select') end.to raise_error(Capybara::ElementNotFound) end end context "on a disabled option" do it "should not select" do @session.select('Other', :from => 'form_title') expect(@session.find_field('form_title').value).not_to eq 'Other' end it "should warn" do expect_any_instance_of(Capybara::Node::Element).to receive(:warn).once @session.select('Other', :from => 'form_title') end end context "with multiple select" do it "should return an empty value" do expect(@session.find_field('Language').value).to eq([]) end it "should return value of the selected options" do @session.select("Ruby", :from => 'Language') @session.select("Javascript", :from => 'Language') expect(@session.find_field('Language').value).to include('Ruby', 'Javascript') end it "should select one option" do @session.select("Ruby", :from => 'Language') @session.click_button('awesome') expect(extract_results(@session)['languages']).to eq(['Ruby']) end it "should select multiple options" do @session.select("Ruby", :from => 'Language') @session.select("Javascript", :from => 'Language') @session.click_button('awesome') expect(extract_results(@session)['languages']).to include('Ruby', 'Javascript') end it "should remain selected if already selected" do @session.select("Ruby", :from => 'Language') @session.select("Javascript", :from => 'Language') @session.select("Ruby", :from => 'Language') @session.click_button('awesome') expect(extract_results(@session)['languages']).to include('Ruby', 'Javascript') end it "should return value attribute rather than content if present" do expect(@session.find_field('Underwear').value).to include('thermal') end end context "with :exact option" do context "when `false`" do it "can match select box approximately" do @session.select("Finish", :from => "Loc", :exact => false) @session.click_button("awesome") expect(extract_results(@session)["locale"]).to eq("fi") end it "can match option approximately" do @session.select("Fin", :from => "Locale", :exact => false) @session.click_button("awesome") expect(extract_results(@session)["locale"]).to eq("fi") end it "can match option approximately when :from not given" do @session.select("made-up language", :exact => false) @session.click_button("awesome") expect(extract_results(@session)["locale"]).to eq("jo") end end context "when `true`" do it "can match select box approximately" do expect do @session.select("Finish", :from => "Loc", :exact => true) end.to raise_error(Capybara::ElementNotFound) end it "can match option approximately" do expect do @session.select("Fin", :from => "Locale", :exact => true) end.to raise_error(Capybara::ElementNotFound) end it "can match option approximately when :from not given" do expect do @session.select("made-up language", :exact => true) end.to raise_error(Capybara::ElementNotFound) end end end end capybara-2.5.0/lib/capybara/spec/session/save_and_open_page_spec.rb0000644000175000017500000000062212573712570024436 0ustar lunarlunarrequire 'launchy' Capybara::SpecHelper.spec '#save_and_open_page' do before do @session.visit '/foo' end after do Dir.glob("capybara-*.html").each do |file| FileUtils.rm(file) end end it "sends open method to launchy" do allow(Launchy).to receive(:open) @session.save_and_open_page expect(Launchy).to have_received(:open).with(/capybara-\d+\.html/) end end capybara-2.5.0/lib/capybara/spec/session/reset_session_spec.rb0000644000175000017500000000434112573712570023530 0ustar lunarlunarCapybara::SpecHelper.spec '#reset_session!' do it "removes cookies" do @session.visit('/set_cookie') @session.visit('/get_cookie') expect(@session).to have_content('test_cookie') @session.reset_session! @session.visit('/get_cookie') expect(@session.body).not_to include('test_cookie') end it "resets current url, host, path" do @session.visit '/foo' expect(@session.current_url).not_to be_empty expect(@session.current_host).not_to be_empty expect(@session.current_path).to eq('/foo') @session.reset_session! expect([nil, '', 'about:blank']).to include(@session.current_url) expect(['', nil]).to include(@session.current_path) expect(@session.current_host).to be_nil end it "resets page body" do @session.visit('/with_html') expect(@session).to have_content('This is a test') expect(@session.find('.//h1').text).to include('This is a test') @session.reset_session! expect(@session.body).not_to include('This is a test') expect(@session).to have_no_selector('.//h1') end it "is synchronous" do @session.visit("/with_html") @session.reset_session! expect(@session).to have_no_selector :xpath, "/html/body/*", wait: false end it "raises any standard errors caught inside the server", :requires => [:server] do quietly { @session.visit("/error") } expect do @session.reset_session! end.to raise_error(TestApp::TestAppError) @session.visit("/") expect(@session.current_path).to eq("/") end it "raises configured errors caught inside the server", :requires => [:server] do prev_errors = Capybara.server_errors Capybara.server_errors = [LoadError] quietly { @session.visit("/error") } expect do @session.reset_session! end.not_to raise_error quietly { @session.visit("/load_error") } expect do @session.reset_session! end.to raise_error(LoadError) Capybara.server_errors = prev_errors end it "ignores server errors when `Capybara.raise_server_errors = false`", :requires => [:server] do Capybara.raise_server_errors = false quietly { @session.visit("/error") } @session.reset_session! @session.visit("/") expect(@session.current_path).to eq("/") end end capybara-2.5.0/lib/capybara/spec/session/has_text_spec.rb0000644000175000017500000002504712573712570022470 0ustar lunarlunarCapybara::SpecHelper.spec '#has_text?' do it "should be true if the given text is on the page at least once" do @session.visit('/with_html') expect(@session).to have_text('est') expect(@session).to have_text('Lorem') expect(@session).to have_text('Redirect') expect(@session).to have_text(:'Redirect') end it "should be true if scoped to an element which has the text" do @session.visit('/with_html') @session.within("//a[@title='awesome title']") do expect(@session).to have_text('labore') end end it "should be false if scoped to an element which does not have the text" do @session.visit('/with_html') @session.within("//a[@title='awesome title']") do expect(@session).not_to have_text('monkey') end end it "should ignore tags" do @session.visit('/with_html') expect(@session).not_to have_text('exercitation ullamco laboris') expect(@session).to have_text('exercitation ullamco laboris') end it "should ignore extra whitespace and newlines" do @session.visit('/with_html') expect(@session).to have_text('text with whitespace') end it "should ignore whitespace and newlines in the search string" do @session.visit('/with_html') expect(@session).to have_text("text with \n\n whitespace") end it "should be false if the given text is not on the page" do @session.visit('/with_html') expect(@session).not_to have_text('xxxxyzzz') expect(@session).not_to have_text('monkey') end it 'should handle single quotes in the text' do @session.visit('/with-quotes') expect(@session).to have_text("can't") end it 'should handle double quotes in the text' do @session.visit('/with-quotes') expect(@session).to have_text(%q{"No," he said}) end it 'should handle mixed single and double quotes in the text' do @session.visit('/with-quotes') expect(@session).to have_text(%q{"you can't do that."}) end it 'should be false if text is in the title tag in the head' do @session.visit('/with_js') expect(@session).not_to have_text('with_js') end it 'should be false if text is inside a script tag in the body' do @session.visit('/with_js') expect(@session).not_to have_text('a javascript comment') expect(@session).not_to have_text('aVar') end it "should be false if the given text is on the page but not visible" do @session.visit('/with_html') expect(@session).not_to have_text('Inside element with hidden ancestor') end it "should be true if :all given and text is invisible." do @session.visit('/with_html') expect(@session).to have_text(:all, 'Some of this text is hidden!') end it "should be true if `Capybara.ignore_hidden_elements = true` and text is invisible." do Capybara.ignore_hidden_elements = false @session.visit('/with_html') expect(@session).to have_text('Some of this text is hidden!') end it "should be true if the text in the page matches given regexp" do @session.visit('/with_html') expect(@session).to have_text(/Lorem/) end it "should be false if the text in the page doesn't match given regexp" do @session.visit('/with_html') expect(@session).not_to have_text(/xxxxyzzz/) end it "should escape any characters that would have special meaning in a regexp" do @session.visit('/with_html') expect(@session).not_to have_text('.orem') end it "should accept non-string parameters" do @session.visit('/with_html') expect(@session).to have_text(42) end it "should be true when passed nil" do # nil is converted to '' when to_s is invoked @session.visit('/with_html') expect(@session).to have_text(nil) end it "should wait for text to appear", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') expect(@session).to have_text("Has been clicked") end context "with between" do it "should be true if the text occurs within the range given" do @session.visit('/with_count') expect(@session).to have_text('count', between: 1..3) expect(@session).to have_text(/count/, between: 2..2) end it "should be false if the text occurs more or fewer times than range" do @session.visit('/with_count') expect(@session).not_to have_text('count', between: 0..1) expect(@session).not_to have_text('count', between: 3..10) expect(@session).not_to have_text(/count/, between: 2...2) end end context "with count" do it "should be true if the text occurs the given number of times" do @session.visit('/with_count') expect(@session).to have_text('count', count: 2) end it "should be false if the text occurs a different number of times than the given" do @session.visit('/with_count') expect(@session).not_to have_text('count', count: 0) expect(@session).not_to have_text('count', count: 1) expect(@session).not_to have_text(/count/, count: 3) end it "should coerce count to an integer" do @session.visit('/with_count') expect(@session).to have_text('count', count: '2') expect(@session).not_to have_text('count', count: '3') end end context "with maximum" do it "should be true when text occurs same or fewer times than given" do @session.visit('/with_count') expect(@session).to have_text('count', maximum: 2) expect(@session).to have_text(/count/, maximum: 3) end it "should be false when text occurs more times than given" do @session.visit('/with_count') expect(@session).not_to have_text('count', maximum: 1) expect(@session).not_to have_text('count', maximum: 0) end it "should coerce maximum to an integer" do @session.visit('/with_count') expect(@session).to have_text('count', maximum: '2') expect(@session).not_to have_text('count', maximum: '1') end end context "with minimum" do it "should be true when text occurs same or more times than given" do @session.visit('/with_count') expect(@session).to have_text('count', minimum: 2) expect(@session).to have_text(/count/, minimum: 0) end it "should be false when text occurs fewer times than given" do @session.visit('/with_count') expect(@session).not_to have_text('count', minimum: 3) end it "should coerce minimum to an integer" do @session.visit('/with_count') expect(@session).to have_text('count', minimum: '2') expect(@session).not_to have_text('count', minimum: '3') end end context "with wait", :requires => [:js] do it "should find element if it appears before given wait duration" do Capybara.using_wait_time(0.1) do @session.visit('/with_js') @session.click_link('Click me') expect(@session).to have_text('Has been clicked', :wait => 0.9) end end end it "should raise an error if an invalid option is passed" do @session.visit('/with_html') expect do expect(@session).to have_text('Lorem', exact: true) end.to raise_error(ArgumentError) end end Capybara::SpecHelper.spec '#has_no_text?' do it "should be false if the given text is on the page at least once" do @session.visit('/with_html') expect(@session).not_to have_no_text('est') expect(@session).not_to have_no_text('Lorem') expect(@session).not_to have_no_text('Redirect') end it "should be false if scoped to an element which has the text" do @session.visit('/with_html') @session.within("//a[@title='awesome title']") do expect(@session).not_to have_no_text('labore') end end it "should be true if scoped to an element which does not have the text" do @session.visit('/with_html') @session.within("//a[@title='awesome title']") do expect(@session).to have_no_text('monkey') end end it "should ignore tags" do @session.visit('/with_html') expect(@session).to have_no_text('exercitation ullamco laboris') expect(@session).not_to have_no_text('exercitation ullamco laboris') end it "should be true if the given text is not on the page" do @session.visit('/with_html') expect(@session).to have_no_text('xxxxyzzz') expect(@session).to have_no_text('monkey') end it 'should handle single quotes in the text' do @session.visit('/with-quotes') expect(@session).not_to have_no_text("can't") end it 'should handle double quotes in the text' do @session.visit('/with-quotes') expect(@session).not_to have_no_text(%q{"No," he said}) end it 'should handle mixed single and double quotes in the text' do @session.visit('/with-quotes') expect(@session).not_to have_no_text(%q{"you can't do that."}) end it 'should be true if text is in the title tag in the head' do @session.visit('/with_js') expect(@session).to have_no_text('with_js') end it 'should be true if text is inside a script tag in the body' do @session.visit('/with_js') expect(@session).to have_no_text('a javascript comment') expect(@session).to have_no_text('aVar') end it "should be true if the given text is on the page but not visible" do @session.visit('/with_html') expect(@session).to have_no_text('Inside element with hidden ancestor') end it "should be false if :all given and text is invisible." do @session.visit('/with_html') expect(@session).not_to have_no_text(:all, 'Some of this text is hidden!') end it "should be false if `Capybara.ignore_hidden_elements = true` and text is invisible." do Capybara.ignore_hidden_elements = false @session.visit('/with_html') expect(@session).not_to have_no_text('Some of this text is hidden!') end it "should be true if the text in the page doesn't match given regexp" do @session.visit('/with_html') expect(@session).to have_no_text(/xxxxyzzz/) end it "should be false if the text in the page matches given regexp" do @session.visit('/with_html') expect(@session).not_to have_no_text(/Lorem/) end it "should escape any characters that would have special meaning in a regexp" do @session.visit('/with_html') expect(@session).to have_no_text('.orem') end it "should wait for text to disappear", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') expect(@session).to have_no_text("I changed it") end context "with wait", :requires => [:js] do it "should not find element if it appears after given wait duration" do @session.visit('/with_js') @session.click_link('Click me') expect(@session).to have_no_text('Has been clicked', :wait => 0.1) end end end capybara-2.5.0/lib/capybara/spec/session/title_spec.rb0000644000175000017500000000071212573712570021762 0ustar lunarlunarCapybara::SpecHelper.spec '#title' do it "should get the title of the page" do @session.visit('/with_title') expect(@session.title).to eq('Test Title') end context "with css as default selector" do before { Capybara.default_selector = :css } it "should get the title of the page" do @session.visit('/with_title') expect(@session.title).to eq('Test Title') end after { Capybara.default_selector = :xpath } end endcapybara-2.5.0/lib/capybara/spec/session/has_field_spec.rb0000644000175000017500000002504312573712570022563 0ustar lunarlunarCapybara::SpecHelper.spec '#has_field' do before { @session.visit('/form') } it "should be true if the field is on the page" do expect(@session).to have_field('Dog') expect(@session).to have_field('form_description') expect(@session).to have_field('Region') expect(@session).to have_field(:'Region') end it "should be false if the field is not on the page" do expect(@session).not_to have_field('Monkey') end context 'with value' do it "should be true if a field with the given value is on the page" do expect(@session).to have_field('First Name', :with => 'John') expect(@session).to have_field('Phone', :with => '+1 555 7021') expect(@session).to have_field('Street', :with => 'Sesame street 66') expect(@session).to have_field('Description', :with => 'Descriptive text goes here') end it "should be false if the given field is not on the page" do expect(@session).not_to have_field('First Name', :with => 'Peter') expect(@session).not_to have_field('Wrong Name', :with => 'John') expect(@session).not_to have_field('Description', :with => 'Monkey') end it "should be true after the field has been filled in with the given value" do @session.fill_in('First Name', :with => 'Jonas') expect(@session).to have_field('First Name', :with => 'Jonas') end it "should be false after the field has been filled in with a different value" do @session.fill_in('First Name', :with => 'Jonas') expect(@session).not_to have_field('First Name', :with => 'John') end end context 'with type' do it "should be true if a field with the given type is on the page" do expect(@session).to have_field('First Name', :type => 'text') expect(@session).to have_field('Html5 Email', :type => 'email') expect(@session).to have_field('Html5 Tel', :type => 'tel') expect(@session).to have_field('Description', :type => 'textarea') expect(@session).to have_field('Languages', :type => 'select') end it "should be false if the given field is not on the page" do expect(@session).not_to have_field('First Name', :type => 'textarea') expect(@session).not_to have_field('Html5 Email', :type => 'tel') expect(@session).not_to have_field('Description', :type => '') expect(@session).not_to have_field('Description', :type => 'email') expect(@session).not_to have_field('Languages', :type => 'textarea') end end end Capybara::SpecHelper.spec '#has_no_field' do before { @session.visit('/form') } it "should be false if the field is on the page" do expect(@session).not_to have_no_field('Dog') expect(@session).not_to have_no_field('form_description') expect(@session).not_to have_no_field('Region') end it "should be true if the field is not on the page" do expect(@session).to have_no_field('Monkey') end context 'with value' do it "should be false if a field with the given value is on the page" do expect(@session).not_to have_no_field('First Name', :with => 'John') expect(@session).not_to have_no_field('Phone', :with => '+1 555 7021') expect(@session).not_to have_no_field('Street', :with => 'Sesame street 66') expect(@session).not_to have_no_field('Description', :with => 'Descriptive text goes here') end it "should be true if the given field is not on the page" do expect(@session).to have_no_field('First Name', :with => 'Peter') expect(@session).to have_no_field('Wrong Name', :with => 'John') expect(@session).to have_no_field('Description', :with => 'Monkey') end it "should be false after the field has been filled in with the given value" do @session.fill_in('First Name', :with => 'Jonas') expect(@session).not_to have_no_field('First Name', :with => 'Jonas') end it "should be true after the field has been filled in with a different value" do @session.fill_in('First Name', :with => 'Jonas') expect(@session).to have_no_field('First Name', :with => 'John') end end context 'with type' do it "should be false if a field with the given type is on the page" do expect(@session).not_to have_no_field('First Name', :type => 'text') expect(@session).not_to have_no_field('Html5 Email', :type => 'email') expect(@session).not_to have_no_field('Html5 Tel', :type => 'tel') expect(@session).not_to have_no_field('Description', :type => 'textarea') expect(@session).not_to have_no_field('Languages', :type => 'select') end it "should be true if the given field is not on the page" do expect(@session).to have_no_field('First Name', :type => 'textarea') expect(@session).to have_no_field('Html5 Email', :type => 'tel') expect(@session).to have_no_field('Description', :type => '') expect(@session).to have_no_field('Description', :type => 'email') expect(@session).to have_no_field('Languages', :type => 'textarea') end end end Capybara::SpecHelper.spec '#has_checked_field?' do before { @session.visit('/form') } it "should be true if a checked field is on the page" do expect(@session).to have_checked_field('gender_female') expect(@session).to have_checked_field('Hamster') end it "should be true for disabled checkboxes if :disabled => true" do expect(@session).to have_checked_field('Disabled Checkbox', :disabled => true) end it "should be false if an unchecked field is on the page" do expect(@session).not_to have_checked_field('form_pets_cat') expect(@session).not_to have_checked_field('Male') end it "should be false if no field is on the page" do expect(@session).not_to have_checked_field('Does Not Exist') end it "should be false for disabled checkboxes by default" do expect(@session).not_to have_checked_field('Disabled Checkbox') end it "should be false for disabled checkboxes if :disabled => false" do expect(@session).not_to have_checked_field('Disabled Checkbox', :disabled => false) end it "should be true after an unchecked checkbox is checked" do @session.check('form_pets_cat') expect(@session).to have_checked_field('form_pets_cat') end it "should be false after a checked checkbox is unchecked" do @session.uncheck('form_pets_dog') expect(@session).not_to have_checked_field('form_pets_dog') end it "should be true after an unchecked radio button is chosen" do @session.choose('gender_male') expect(@session).to have_checked_field('gender_male') end it "should be false after another radio button in the group is chosen" do @session.choose('gender_male') expect(@session).not_to have_checked_field('gender_female') end end Capybara::SpecHelper.spec '#has_no_checked_field?' do before { @session.visit('/form') } it "should be false if a checked field is on the page" do expect(@session).not_to have_no_checked_field('gender_female') expect(@session).not_to have_no_checked_field('Hamster') end it "should be false for disabled checkboxes if :disabled => true" do expect(@session).not_to have_no_checked_field('Disabled Checkbox', :disabled => true) end it "should be true if an unchecked field is on the page" do expect(@session).to have_no_checked_field('form_pets_cat') expect(@session).to have_no_checked_field('Male') end it "should be true if no field is on the page" do expect(@session).to have_no_checked_field('Does Not Exist') end it "should be true for disabled checkboxes by default" do expect(@session).to have_no_checked_field('Disabled Checkbox') end it "should be true for disabled checkboxes if :disabled => false" do expect(@session).to have_no_checked_field('Disabled Checkbox', :disabled => false) end end Capybara::SpecHelper.spec '#has_unchecked_field?' do before { @session.visit('/form') } it "should be false if a checked field is on the page" do expect(@session).not_to have_unchecked_field('gender_female') expect(@session).not_to have_unchecked_field('Hamster') end it "should be true if an unchecked field is on the page" do expect(@session).to have_unchecked_field('form_pets_cat') expect(@session).to have_unchecked_field('Male') end it "should be true for disabled unchecked fields if :disabled => true" do expect(@session).to have_unchecked_field('Disabled Unchecked Checkbox', :disabled => true) end it "should be false if no field is on the page" do expect(@session).not_to have_unchecked_field('Does Not Exist') end it "should be false for disabled unchecked fields by default" do expect(@session).not_to have_unchecked_field('Disabled Unchecked Checkbox') end it "should be false for disabled unchecked fields if :disabled => false" do expect(@session).not_to have_unchecked_field('Disabled Unchecked Checkbox', :disabled => false) end it "should be false after an unchecked checkbox is checked" do @session.check('form_pets_cat') expect(@session).not_to have_unchecked_field('form_pets_cat') end it "should be true after a checked checkbox is unchecked" do @session.uncheck('form_pets_dog') expect(@session).to have_unchecked_field('form_pets_dog') end it "should be false after an unchecked radio button is chosen" do @session.choose('gender_male') expect(@session).not_to have_unchecked_field('gender_male') end it "should be true after another radio button in the group is chosen" do @session.choose('gender_male') expect(@session).to have_unchecked_field('gender_female') end end Capybara::SpecHelper.spec '#has_no_unchecked_field?' do before { @session.visit('/form') } it "should be true if a checked field is on the page" do expect(@session).to have_no_unchecked_field('gender_female') expect(@session).to have_no_unchecked_field('Hamster') end it "should be false if an unchecked field is on the page" do expect(@session).not_to have_no_unchecked_field('form_pets_cat') expect(@session).not_to have_no_unchecked_field('Male') end it "should be false for disabled unchecked fields if :disabled => true" do expect(@session).not_to have_no_unchecked_field('Disabled Unchecked Checkbox', :disabled => true) end it "should be true if no field is on the page" do expect(@session).to have_no_unchecked_field('Does Not Exist') end it "should be true for disabled unchecked fields by default" do expect(@session).to have_no_unchecked_field('Disabled Unchecked Checkbox') end it "should be true for disabled unchecked fields if :disabled => false" do expect(@session).to have_no_unchecked_field('Disabled Unchecked Checkbox', :disabled => false) end end capybara-2.5.0/lib/capybara/spec/session/has_xpath_spec.rb0000644000175000017500000001167712573712570022634 0ustar lunarlunarCapybara::SpecHelper.spec '#has_xpath?' do before do @session.visit('/with_html') end it "should be true if the given selector is on the page" do expect(@session).to have_xpath("//p") expect(@session).to have_xpath("//p//a[@id='foo']") expect(@session).to have_xpath("//p[contains(.,'est')]") end it "should be false if the given selector is not on the page" do expect(@session).not_to have_xpath("//abbr") expect(@session).not_to have_xpath("//p//a[@id='doesnotexist']") expect(@session).not_to have_xpath("//p[contains(.,'thisstringisnotonpage')]") end it "should use xpath even if default selector is CSS" do Capybara.default_selector = :css expect(@session).not_to have_xpath("//p//a[@id='doesnotexist']") end it "should respect scopes" do @session.within "//p[@id='first']" do expect(@session).to have_xpath(".//a[@id='foo']") expect(@session).not_to have_xpath(".//a[@id='red']") end end it "should wait for content to appear", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') expect(@session).to have_xpath("//input[@type='submit' and @value='New Here']") end context "with count" do it "should be true if the content occurs the given number of times" do expect(@session).to have_xpath("//p", :count => 3) expect(@session).to have_xpath("//p//a[@id='foo']", :count => 1) expect(@session).to have_xpath("//p[contains(.,'est')]", :count => 1) expect(@session).to have_xpath("//p//a[@id='doesnotexist']", :count => 0) end it "should be false if the content occurs a different number of times than the given" do expect(@session).not_to have_xpath("//p", :count => 6) expect(@session).not_to have_xpath("//p//a[@id='foo']", :count => 2) expect(@session).not_to have_xpath("//p[contains(.,'est')]", :count => 5) expect(@session).not_to have_xpath("//p//a[@id='doesnotexist']", :count => 1) end end context "with text" do it "should discard all matches where the given string is not contained" do expect(@session).to have_xpath("//p//a", :text => "Redirect", :count => 1) expect(@session).not_to have_xpath("//p", :text => "Doesnotexist") end it "should discard all matches where the given regexp is not matched" do expect(@session).to have_xpath("//p//a", :text => /re[dab]i/i, :count => 1) expect(@session).not_to have_xpath("//p//a", :text => /Red$/) end end end Capybara::SpecHelper.spec '#has_no_xpath?' do before do @session.visit('/with_html') end it "should be false if the given selector is on the page" do expect(@session).not_to have_no_xpath("//p") expect(@session).not_to have_no_xpath("//p//a[@id='foo']") expect(@session).not_to have_no_xpath("//p[contains(.,'est')]") end it "should be true if the given selector is not on the page" do expect(@session).to have_no_xpath("//abbr") expect(@session).to have_no_xpath("//p//a[@id='doesnotexist']") expect(@session).to have_no_xpath("//p[contains(.,'thisstringisnotonpage')]") end it "should use xpath even if default selector is CSS" do Capybara.default_selector = :css expect(@session).to have_no_xpath("//p//a[@id='doesnotexist']") end it "should respect scopes" do @session.within "//p[@id='first']" do expect(@session).not_to have_no_xpath(".//a[@id='foo']") expect(@session).to have_no_xpath(".//a[@id='red']") end end it "should wait for content to disappear", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') expect(@session).to have_no_xpath("//p[@id='change']") end context "with count" do it "should be false if the content occurs the given number of times" do expect(@session).not_to have_no_xpath("//p", :count => 3) expect(@session).not_to have_no_xpath("//p//a[@id='foo']", :count => 1) expect(@session).not_to have_no_xpath("//p[contains(.,'est')]", :count => 1) expect(@session).not_to have_no_xpath("//p//a[@id='doesnotexist']", :count => 0) end it "should be true if the content occurs a different number of times than the given" do expect(@session).to have_no_xpath("//p", :count => 6) expect(@session).to have_no_xpath("//p//a[@id='foo']", :count => 2) expect(@session).to have_no_xpath("//p[contains(.,'est')]", :count => 5) expect(@session).to have_no_xpath("//p//a[@id='doesnotexist']", :count => 1) end end context "with text" do it "should discard all matches where the given string is contained" do expect(@session).not_to have_no_xpath("//p//a", :text => "Redirect", :count => 1) expect(@session).to have_no_xpath("//p", :text => "Doesnotexist") end it "should discard all matches where the given regexp is matched" do expect(@session).not_to have_no_xpath("//p//a", :text => /re[dab]i/i, :count => 1) expect(@session).to have_no_xpath("//p//a", :text => /Red$/) end end end capybara-2.5.0/lib/capybara/spec/session/evaluate_script_spec.rb0000644000175000017500000000035512573712570024036 0ustar lunarlunarCapybara::SpecHelper.spec "#evaluate_script", :requires => [:js] do it "should evaluate the given script and return whatever it produces" do @session.visit('/with_js') expect(@session.evaluate_script("1+3")).to eq(4) end end capybara-2.5.0/lib/capybara/spec/session/body_spec.rb0000644000175000017500000000164112573712570021600 0ustar lunarlunarCapybara::SpecHelper.spec '#body' do it "should return the unmodified page body" do @session.visit('/') expect(@session).to have_content('Hello world!') # wait for content to appear if visit is async expect(@session.body).to include('Hello world!') end if "".respond_to?(:encoding) context "encoding of response between ascii and utf8" do it "should be valid with html entities" do @session.visit('/with_html_entities') expect(@session).to have_content('Encoding') # wait for content to appear if visit is async expect { @session.body.encode!("UTF-8") }.not_to raise_error end it "should be valid without html entities" do @session.visit('/with_html') expect(@session).to have_content('This is a test') # wait for content to appear if visit is async expect { @session.body.encode!("UTF-8") }.not_to raise_error end end end end capybara-2.5.0/lib/capybara/spec/session/click_button_spec.rb0000644000175000017500000003417512573712570023333 0ustar lunarlunarCapybara::SpecHelper.spec '#click_button' do before do @session.visit('/form') end it "should wait for asynchronous load", :requires => [:js] do @session.visit('/with_js') @session.click_link('Click me') @session.click_button('New Here') end it "casts to string" do @session.click_button(:'Relative Action') expect(extract_results(@session)['relative']).to eq('Relative Action') expect(@session.current_path).to eq('/relative') end context "with multiple values with the same name" do it "should use the latest given value" do @session.check('Terms of Use') @session.click_button('awesome') expect(extract_results(@session)['terms_of_use']).to eq('1') end end context "with a form that has a relative url as an action" do it "should post to the correct url" do @session.click_button('Relative Action') expect(extract_results(@session)['relative']).to eq('Relative Action') expect(@session.current_path).to eq('/relative') end end context "with a form that has no action specified" do it "should post to the correct url" do @session.click_button('No Action') expect(extract_results(@session)['no_action']).to eq('No Action') expect(@session.current_path).to eq('/form') end end context "with value given on a submit button" do context "on a form with HTML5 fields" do before do @session.click_button('html5_submit') @results = extract_results(@session) end it "should serialise and submit search fields" do expect(@results['html5_search']).to eq('what are you looking for') end it "should serialise and submit email fields" do expect(@results['html5_email']).to eq('person@email.com') end it "should serialise and submit url fields" do expect(@results['html5_url']).to eq('http://www.example.com') end it "should serialise and submit tel fields" do expect(@results['html5_tel']).to eq('911') end it "should serialise and submit color fields" do expect(@results['html5_color'].upcase).to eq('#FFFFFF') end end context "on an HTML4 form" do before do @session.click_button('awesome') @results = extract_results(@session) end it "should serialize and submit text fields" do expect(@results['first_name']).to eq('John') end it "should escape fields when submitting" do expect(@results['phone']).to eq('+1 555 7021') end it "should serialize and submit password fields" do expect(@results['password']).to eq('seeekrit') end it "should serialize and submit hidden fields" do expect(@results['token']).to eq('12345') end it "should not serialize fields from other forms" do expect(@results['middle_name']).to be_nil end it "should submit the button that was clicked, but not other buttons" do expect(@results['awesome']).to eq('awesome') expect(@results['crappy']).to be_nil end it "should serialize radio buttons" do expect(@results['gender']).to eq('female') end it "should default radio value to 'on' if none specified" do expect(@results['valueless_radio']).to eq('on') end it "should serialize check boxes" do expect(@results['pets']).to include('dog', 'hamster') expect(@results['pets']).not_to include('cat') end it "should default checkbox value to 'on' if none specififed" do expect(@results['valueless_checkbox']).to eq('on') end it "should serialize text areas" do expect(@results['description']).to eq('Descriptive text goes here') end it "should serialize select tag with values" do expect(@results['locale']).to eq('en') end it "should serialize select tag without values" do expect(@results['region']).to eq('Norway') end it "should serialize first option for select tag with no selection" do expect(@results['city']).to eq('London') end it "should not serialize a select tag without options" do expect(@results['tendency']).to be_nil end it "should convert lf to cr/lf in submitted textareas" do expect(@results['newline']).to eq("\r\nNew line after and before textarea tag\r\n") end it "should not submit disabled fields" do expect(@results['disabled_text_field']).to be_nil expect(@results['disabled_textarea']).to be_nil expect(@results['disabled_checkbox']).to be_nil expect(@results['disabled_radio']).to be_nil expect(@results['disabled_select']).to be_nil expect(@results['disabled_file']).to be_nil end end end context "with id given on a submit button" do it "should submit the associated form" do @session.click_button('awe123') expect(extract_results(@session)['first_name']).to eq('John') end it "should work with partial matches" do @session.click_button('Go') expect(@session).to have_content('You landed') end end context "with title given on a submit button" do it "should submit the associated form" do @session.click_button('What an Awesome Button') expect(extract_results(@session)['first_name']).to eq('John') end it "should work with partial matches" do @session.click_button('What an Awesome') expect(extract_results(@session)['first_name']).to eq('John') end end context "with fields associated with the form using the form attribute" do before do @session.click_button('submit_form1') @results = extract_results(@session) end it "should serialize and submit text fields" do expect(@results['outside_input']).to eq('outside_input') end it "should serialize text areas" do expect(@results['outside_textarea']).to eq('Some text here') end it "should serialize select tags" do expect(@results['outside_select']).to eq('Ruby') end it "should not serliaze fields associated with a different form" do expect(@results['for_form2']).to be_nil end end context "with submit button outside the form defined by