nimboids-capybara 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. data/History.txt +289 -0
  2. data/README.rdoc +722 -0
  3. data/lib/capybara.rb +252 -0
  4. data/lib/capybara/cucumber.rb +28 -0
  5. data/lib/capybara/driver/base.rb +64 -0
  6. data/lib/capybara/driver/node.rb +74 -0
  7. data/lib/capybara/dsl.rb +168 -0
  8. data/lib/capybara/node/actions.rb +162 -0
  9. data/lib/capybara/node/base.rb +63 -0
  10. data/lib/capybara/node/document.rb +25 -0
  11. data/lib/capybara/node/element.rb +201 -0
  12. data/lib/capybara/node/finders.rb +197 -0
  13. data/lib/capybara/node/matchers.rb +417 -0
  14. data/lib/capybara/node/simple.rb +132 -0
  15. data/lib/capybara/rack_test/browser.rb +121 -0
  16. data/lib/capybara/rack_test/driver.rb +80 -0
  17. data/lib/capybara/rack_test/form.rb +80 -0
  18. data/lib/capybara/rack_test/node.rb +105 -0
  19. data/lib/capybara/rails.rb +17 -0
  20. data/lib/capybara/rspec.rb +26 -0
  21. data/lib/capybara/rspec/features.rb +22 -0
  22. data/lib/capybara/rspec/matchers.rb +154 -0
  23. data/lib/capybara/selector.rb +89 -0
  24. data/lib/capybara/selenium/driver.rb +163 -0
  25. data/lib/capybara/selenium/node.rb +91 -0
  26. data/lib/capybara/server.rb +90 -0
  27. data/lib/capybara/session.rb +321 -0
  28. data/lib/capybara/spec/driver.rb +301 -0
  29. data/lib/capybara/spec/fixtures/capybara.jpg +3 -0
  30. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  31. data/lib/capybara/spec/public/test.js +43 -0
  32. data/lib/capybara/spec/session.rb +154 -0
  33. data/lib/capybara/spec/session/all_spec.rb +78 -0
  34. data/lib/capybara/spec/session/attach_file_spec.rb +73 -0
  35. data/lib/capybara/spec/session/check_spec.rb +65 -0
  36. data/lib/capybara/spec/session/choose_spec.rb +26 -0
  37. data/lib/capybara/spec/session/click_button_spec.rb +304 -0
  38. data/lib/capybara/spec/session/click_link_or_button_spec.rb +36 -0
  39. data/lib/capybara/spec/session/click_link_spec.rb +119 -0
  40. data/lib/capybara/spec/session/current_host_spec.rb +68 -0
  41. data/lib/capybara/spec/session/current_url_spec.rb +15 -0
  42. data/lib/capybara/spec/session/fill_in_spec.rb +125 -0
  43. data/lib/capybara/spec/session/find_button_spec.rb +18 -0
  44. data/lib/capybara/spec/session/find_by_id_spec.rb +18 -0
  45. data/lib/capybara/spec/session/find_field_spec.rb +26 -0
  46. data/lib/capybara/spec/session/find_link_spec.rb +19 -0
  47. data/lib/capybara/spec/session/find_spec.rb +149 -0
  48. data/lib/capybara/spec/session/first_spec.rb +105 -0
  49. data/lib/capybara/spec/session/has_button_spec.rb +32 -0
  50. data/lib/capybara/spec/session/has_content_spec.rb +106 -0
  51. data/lib/capybara/spec/session/has_css_spec.rb +243 -0
  52. data/lib/capybara/spec/session/has_field_spec.rb +192 -0
  53. data/lib/capybara/spec/session/has_link_spec.rb +37 -0
  54. data/lib/capybara/spec/session/has_select_spec.rb +129 -0
  55. data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
  56. data/lib/capybara/spec/session/has_table_spec.rb +96 -0
  57. data/lib/capybara/spec/session/has_xpath_spec.rb +123 -0
  58. data/lib/capybara/spec/session/headers.rb +19 -0
  59. data/lib/capybara/spec/session/javascript.rb +289 -0
  60. data/lib/capybara/spec/session/response_code.rb +19 -0
  61. data/lib/capybara/spec/session/select_spec.rb +113 -0
  62. data/lib/capybara/spec/session/text_spec.rb +19 -0
  63. data/lib/capybara/spec/session/uncheck_spec.rb +21 -0
  64. data/lib/capybara/spec/session/unselect_spec.rb +61 -0
  65. data/lib/capybara/spec/session/within_spec.rb +178 -0
  66. data/lib/capybara/spec/test_app.rb +142 -0
  67. data/lib/capybara/spec/views/buttons.erb +4 -0
  68. data/lib/capybara/spec/views/fieldsets.erb +29 -0
  69. data/lib/capybara/spec/views/form.erb +365 -0
  70. data/lib/capybara/spec/views/frame_one.erb +8 -0
  71. data/lib/capybara/spec/views/frame_two.erb +8 -0
  72. data/lib/capybara/spec/views/header_links.erb +7 -0
  73. data/lib/capybara/spec/views/host_links.erb +12 -0
  74. data/lib/capybara/spec/views/popup_one.erb +8 -0
  75. data/lib/capybara/spec/views/popup_two.erb +8 -0
  76. data/lib/capybara/spec/views/postback.erb +13 -0
  77. data/lib/capybara/spec/views/tables.erb +122 -0
  78. data/lib/capybara/spec/views/with_html.erb +78 -0
  79. data/lib/capybara/spec/views/with_html_entities.erb +1 -0
  80. data/lib/capybara/spec/views/with_js.erb +48 -0
  81. data/lib/capybara/spec/views/with_scope.erb +36 -0
  82. data/lib/capybara/spec/views/with_simple_html.erb +1 -0
  83. data/lib/capybara/spec/views/within_frames.erb +10 -0
  84. data/lib/capybara/spec/views/within_popups.erb +25 -0
  85. data/lib/capybara/util/save_and_open_page.rb +44 -0
  86. data/lib/capybara/util/timeout.rb +27 -0
  87. data/lib/capybara/version.rb +3 -0
  88. data/spec/basic_node_spec.rb +77 -0
  89. data/spec/capybara_spec.rb +46 -0
  90. data/spec/driver/rack_test_driver_spec.rb +89 -0
  91. data/spec/driver/selenium_driver_spec.rb +50 -0
  92. data/spec/dsl_spec.rb +253 -0
  93. data/spec/fixtures/selenium_driver_rspec_failure.rb +8 -0
  94. data/spec/fixtures/selenium_driver_rspec_success.rb +8 -0
  95. data/spec/rspec/features_spec.rb +45 -0
  96. data/spec/rspec/matchers_spec.rb +495 -0
  97. data/spec/rspec_spec.rb +53 -0
  98. data/spec/save_and_open_page_spec.rb +155 -0
  99. data/spec/server_spec.rb +89 -0
  100. data/spec/session/rack_test_session_spec.rb +55 -0
  101. data/spec/session/selenium_session_spec.rb +26 -0
  102. data/spec/spec_helper.rb +30 -0
  103. data/spec/string_spec.rb +77 -0
  104. data/spec/timeout_spec.rb +28 -0
  105. metadata +346 -0
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <title>This is the title of popup two</title>
4
+ </head>
5
+ <body>
6
+ <div id="divInPopupTwo">This is the text of divInPopupTwo</div>
7
+ </body>
8
+ </html>
@@ -0,0 +1,13 @@
1
+ <h1>Postback</h1>
2
+
3
+ <form method="get">
4
+ <p>
5
+ <input type="submit" value="With no action">
6
+ </p>
7
+ </form>
8
+
9
+ <form action="" method="get">
10
+ <p>
11
+ <input type="submit" value="With blank action">
12
+ </p>
13
+ </form>
@@ -0,0 +1,122 @@
1
+ <form action="/form" method="post">
2
+ <table id="agent_table">
3
+ <caption>Agent</caption>
4
+
5
+ <tr>
6
+ <td>
7
+ <label for="form_agent_name">Name</label>
8
+ </td>
9
+ <td>
10
+ <input type="text" name="form[agent_name]" value="James" id="form_agent_name"/>
11
+ </td>
12
+ </tr>
13
+
14
+ <tr>
15
+ <td colspan="2">
16
+ <input type="submit" value="Create"/>
17
+ </td>
18
+ </tr>
19
+ </table>
20
+ </form>
21
+
22
+ <form action="/form" method="post">
23
+ <table id="girl_table">
24
+ <caption>Girl</caption>
25
+
26
+ <tr>
27
+ <td>
28
+ <label for="form_girl_name">Name</label>
29
+ </td>
30
+ <td>
31
+ <input type="text" name="form[girl_name]" value="Vesper" id="form_girl_name"/>
32
+ </td>
33
+ </tr>
34
+
35
+ <tr>
36
+ <td colspan="2">
37
+ <input type="submit" value="Create"/>
38
+ </td>
39
+ </tr>
40
+ </table>
41
+ </form>
42
+
43
+ <form action="/form" method="post">
44
+ <table id="villain_table">
45
+ <caption>Villain</caption>
46
+
47
+ <tr>
48
+ <td>
49
+ <label for="form_villain_name">Name</label>
50
+ </td>
51
+ <td>
52
+ <input type="text" name="form[villain_name]" value="Ernst" id="form_villain_name"/>
53
+ </td>
54
+ </tr>
55
+
56
+ <tr>
57
+ <td colspan="2">
58
+ <input type="submit" value="Create"/>
59
+ </td>
60
+ </tr>
61
+ </table>
62
+ </form>
63
+
64
+ <table>
65
+ <caption>Ransom</caption>
66
+
67
+ <thead>
68
+ <tr>
69
+ <th>Year</th>
70
+ <th>Governmental</th>
71
+ <th>Private</th>
72
+ </tr>
73
+ </thead>
74
+
75
+ <tbody>
76
+ <tr>
77
+ <th scope="row">2007</th>
78
+ <td>$300</td>
79
+ <td>$100</td>
80
+ </tr>
81
+ <tr>
82
+ <th scope="row">2008</th>
83
+ <td>$123</td>
84
+ <td>$897</td>
85
+ </tr>
86
+ <tr>
87
+ <th scope="row">2009</th>
88
+ <td>$543</td>
89
+ <td>$99</td>
90
+ </tr>
91
+ </tbody>
92
+ </table>
93
+
94
+ <table>
95
+ <caption>Deaths</caption>
96
+
97
+ <thead>
98
+ <tr>
99
+ <th>Year</th>
100
+ <th>Sharks with lasers</th>
101
+ <th>Flaming volcano</th>
102
+ </tr>
103
+ </thead>
104
+
105
+ <tbody>
106
+ <tr>
107
+ <th scope="row">2007</th>
108
+ <td>66</td>
109
+ <td>7</td>
110
+ </tr>
111
+ <tr>
112
+ <th scope="row">2008</th>
113
+ <td>123</td>
114
+ <td>12</td>
115
+ </tr>
116
+ <tr>
117
+ <th scope="row">2009</th>
118
+ <td>913</td>
119
+ <td>13</td>
120
+ </tr>
121
+ </tbody>
122
+ </table>
@@ -0,0 +1,78 @@
1
+ <h1>This is a test</h1>
2
+
3
+ <h2 class="no text"></h2>
4
+ <h2 class="no text"></h2>
5
+ <h2 class="head" id="h2one">Header Class Test One</h2>
6
+ <h2 class="head" id="h2two">Header Class Test Two</h2>
7
+ <h2 class="head">Header Class Test Three</h2>
8
+ <h2 class="head">Header Class Test Four</h2>
9
+ <h2 class="head">Header Class Test Five</h2>
10
+
11
+ <p class="para" id="first">
12
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
13
+ tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple">labore</a>
14
+ et dolore magna aliqua. Ut enim ad minim veniam,
15
+ quis nostrud exercitation <a href="/foo" id="foo">ullamco</a> laboris nisi
16
+ ut aliquip ex ea commodo consequat.
17
+ <a href="/with_simple_html"><img width="20" height="20" alt="awesome image" /></a>
18
+ </p>
19
+
20
+ <p class="para" id="second">
21
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
22
+ dolore eu fugiat <a href="/redirect" id="red">Redirect</a> pariatur. Excepteur sint occaecat cupidatat non proident,
23
+ sunt in culpa qui officia
24
+ text with
25
+ whitespace
26
+ id est laborum.
27
+ </p>
28
+
29
+ <p>
30
+ <input type="text" id="test_field" value="monkey"/>
31
+ <textarea id="normal">
32
+ banana</textarea>
33
+ <textarea id="additional_newline">
34
+
35
+ banana</textarea>
36
+ <a href="/redirect_back">BackToMyself</a>
37
+ <a title="twas a fine link" href="/redirect">A link came first</a>
38
+ <a title="a fine link" href="/with_simple_html">A link</a>
39
+ <a title="a fine link with data method" data-method="delete" href="/delete">A link with data-method</a>
40
+ <a>No Href</a>
41
+ <a href="">Blank Href</a>
42
+ <a href="#">Blank Anchor</a>
43
+ <a href="#anchor">Anchor</a>
44
+ <a href="/with_simple_html#anchor">Anchor on different page</a>
45
+ <a href="/with_html#anchor">Anchor on same page</a>
46
+ <a href="with_html">Relative</a>
47
+ <input type="text" value="" id="test_field">
48
+ <input type="text" checked="checked" id="checked_field">
49
+ <a href="/redirect"><img width="20" height="20" alt="very fine image" /></a>
50
+ <a href="/with_simple_html"><img width="20" height="20" alt="fine image" /></a>
51
+
52
+ <a href="?query_string=true">Naked Query String</a>
53
+ <% if params[:query_string] %>
54
+ <em>Query String sent</em>
55
+ <% end %>
56
+ </p>
57
+
58
+ <div id="hidden" style="display: none;">
59
+ <div id="hidden_via_ancestor">Inside element with hidden ancestor</div>
60
+ <a href="/with_simple_html" title="awesome title" class="simple">hidden link</a>
61
+ </div>
62
+
63
+ <div style="display: none;">
64
+ <a id="first_invisble" class="hidden">first hidden link</a>
65
+ </div>
66
+
67
+ <div style="display: none;">
68
+ <a id="invisible" class="visibility hidden">hidden link</a>
69
+ </div>
70
+
71
+ <div>
72
+ <a id="visible" class="visibility">visible link</a>
73
+ </div>
74
+
75
+ <ul>
76
+ <li id="john_monkey">Monkey John</li>
77
+ <li id="paul_monkey">Monkey Paul</li>
78
+ </ul>
@@ -0,0 +1 @@
1
+ Encoding with &mdash; html entities &raquo;
@@ -0,0 +1,48 @@
1
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
2
+ <head>
3
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
4
+ <title>with_js</title>
5
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>
6
+ <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/jquery-ui.min.js" type="text/javascript" charset="utf-8"></script>
7
+ <script src="/test.js" type="text/javascript" charset="utf-8"></script>
8
+ </head>
9
+
10
+ <body id="with_js">
11
+ <h1>FooBar</h1>
12
+
13
+ <p id="change">This is text</p>
14
+ <div id="drag">
15
+ <p>This is a draggable element.</p>
16
+ </div>
17
+ <div id="drop">
18
+ <p>It should be dropped here.</p>
19
+ </div>
20
+
21
+ <p><a href="#" id="clickable">Click me</a></p>
22
+
23
+ <p>
24
+ <select id="waiter">
25
+ <option>Foo</option>
26
+ <option>My Waiting Option</option>
27
+ </select>
28
+ </p>
29
+
30
+ <p>
31
+ <input type="text" name="with_focus_event" value="" id="with_focus_event"/>
32
+ </p>
33
+
34
+ <p>
35
+ <input type="checkbox" id="checkbox_with_event"/>
36
+ </p>
37
+
38
+ <p>
39
+ <input type="submit" id="fire_ajax_request" value="Fire Ajax Request"/>
40
+ </p>
41
+
42
+ <p>
43
+ <a id="reload-link" href="#">Reload!</a>
44
+ <div id="reload-me"><em>waiting to be reloaded</em></div>
45
+ </p>
46
+ </body>
47
+ </html>
48
+
@@ -0,0 +1,36 @@
1
+ <h1>This page is used for testing various scopes</h1>
2
+
3
+ <p id="for_foo">
4
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
5
+ incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia.
6
+ <a href="/redirect">Go</a>
7
+ </p>
8
+
9
+ <div id="for_bar">
10
+ <ul>
11
+ <li>With Simple HTML: <a href="/with_simple_html">Go</a>
12
+ <form action="/redirect" method="post" accept-charset="utf-8">
13
+ <p>
14
+ <label for="simple_first_name">First Name</label>
15
+ <input type="text" name="first_name" value="John" id="simple_first_name"/>
16
+ </p>
17
+ <p><input type="submit" value="Go"/></p>
18
+ </form>
19
+ </li>
20
+ <li>Bar: <a href="/foo">Go</a>
21
+ <form action="/form" method="post" accept-charset="utf-8">
22
+ <p>
23
+ <label for="bar_first_name">First Name</label>
24
+ <input type="text" name="form[first_name]" value="Peter" id="bar_first_name"/>
25
+ </p>
26
+ <p><input type="submit" value="Go"/></p>
27
+ </form>
28
+ </li>
29
+ </ul>
30
+ </div>
31
+
32
+ <div id="another_foo">
33
+ <ul>
34
+ <li>With Simple HTML: <a href="/">Go</a>
35
+ </ul>
36
+ </div>
@@ -0,0 +1,10 @@
1
+ <html>
2
+ <head>
3
+ <title>With Frames</title>
4
+ </head>
5
+ <body>
6
+ <div id="divInMainWindow">This is the text for divInMainWindow</div>
7
+ <iframe src="/frame_one" id="frameOne"></iframe>
8
+ <iframe src="/frame_two" id="frameTwo"></iframe>
9
+ </body>
10
+ </html>
@@ -0,0 +1,25 @@
1
+ <html>
2
+ <head>
3
+ <title>With Popups</title>
4
+ <script language="javascript" type="text/javascript">
5
+ <!--
6
+
7
+ function popItUp(name, url) {
8
+ newwindow=window.open(url,name,'height=200,width=150');
9
+ if (window.focus) { newwindow.focus() }
10
+ return false;
11
+ }
12
+
13
+ function init() {
14
+ popItUp('firstPopup', '/popup_one');
15
+ popItUp('secondPopup', '/popup_two');
16
+ }
17
+ window.onload = init;
18
+
19
+ // -->
20
+ </script>
21
+ </head>
22
+ <body>
23
+ <div id="divInMainWindow">This is the text for divInMainWindow</div>
24
+ </body>
25
+ </html>
@@ -0,0 +1,44 @@
1
+ module Capybara
2
+ class << self
3
+ def save_page(html, file_name=nil)
4
+ file_name ||= "capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}#{rand(10**10)}.html"
5
+ name = File.join(*[Capybara.save_and_open_page_path, file_name].compact)
6
+
7
+ unless Capybara.save_and_open_page_path.nil? || File.directory?(Capybara.save_and_open_page_path )
8
+ FileUtils.mkdir_p(Capybara.save_and_open_page_path)
9
+ end
10
+ FileUtils.touch(name) unless File.exist?(name)
11
+
12
+ tempfile = File.new(name,'w')
13
+ tempfile.write(rewrite_css_and_image_references(html))
14
+ tempfile.close
15
+ tempfile.path
16
+ end
17
+
18
+ def save_and_open_page(html, file_name=nil)
19
+ open_in_browser save_page(html, file_name)
20
+ end
21
+
22
+ protected
23
+
24
+ def open_in_browser(path) # :nodoc
25
+ require "launchy"
26
+ Launchy.open(path)
27
+ rescue LoadError
28
+ warn "Sorry, you need to install launchy (`gem install launchy`) and " <<
29
+ "make sure it's available to open pages with `save_and_open_page`."
30
+ end
31
+
32
+ def rewrite_css_and_image_references(response_html) # :nodoc:
33
+ root = Capybara.asset_root
34
+ return response_html unless root
35
+ directories = Dir.new(root).entries.select { |name|
36
+ (root+name).directory? and not name.to_s =~ /^\./
37
+ }
38
+ if not directories.empty?
39
+ response_html.gsub!(/("|')\/(#{directories.join('|')})/, '\1' + root.to_s + '/\2')
40
+ end
41
+ return response_html
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,27 @@
1
+ module Capybara
2
+ class << self
3
+
4
+ ##
5
+ # Provides timeout similar to standard library Timeout, but avoids threads
6
+ #
7
+ def timeout(seconds = 1, driver = nil, error_message = nil, &block)
8
+ start_time = Time.now
9
+
10
+ result = nil
11
+
12
+ until result
13
+ return result if result = yield
14
+
15
+ delay = seconds - (Time.now - start_time)
16
+ if delay <= 0
17
+ raise TimeoutError, error_message || "timed out"
18
+ end
19
+
20
+ driver && driver.wait_until(delay)
21
+
22
+ sleep(0.05)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module Capybara
2
+ VERSION = '1.1.2'
3
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Capybara do
4
+ describe '.string' do
5
+ let :string do
6
+ Capybara.string <<-STRING
7
+ <div id="page">
8
+ <div id="content">
9
+ <h1 data="fantastic">Awesome</h1>
10
+ <p>Yes it is</p>
11
+ </div>
12
+
13
+ <div id="footer" style="display: none">
14
+ <p>c2010</p>
15
+ <p>Jonas Nicklas</p>
16
+ <input type="text" name="foo" value="bar"/>
17
+ <select name="animal">
18
+ <option>Monkey</option>
19
+ <option selected="selected">Capybara</option>
20
+ </select>
21
+ </div>
22
+ </div>
23
+ STRING
24
+ end
25
+
26
+ it "allows using matchers" do
27
+ string.should have_css('#page')
28
+ string.should_not have_css('#does-not-exist')
29
+ end
30
+
31
+ it "allows using custom matchers" do
32
+ Capybara.add_selector :lifeform do
33
+ xpath { |name| "//option[contains(.,'#{name}')]" }
34
+ end
35
+ string.should have_selector(:page)
36
+ string.should_not have_selector(:'does-not-exist')
37
+ string.should have_selector(:lifeform, "Monkey")
38
+ string.should_not have_selector(:lifeform, "Gorilla")
39
+ end
40
+
41
+ it "allows using matchers with text option" do
42
+ string.should have_css('h1', :text => 'Awesome')
43
+ string.should_not have_css('h1', :text => 'Not so awesome')
44
+ end
45
+
46
+ it "allows finding only visible nodes" do
47
+ string.all('//p', :text => 'c2010', :visible => true).should be_empty
48
+ string.all('//p', :text => 'c2010', :visible => false).should have(1).element
49
+ end
50
+
51
+ it "allows finding elements and extracting text from them" do
52
+ string.find('//h1').text.should == 'Awesome'
53
+ end
54
+
55
+ it "allows finding elements and extracting attributes from them" do
56
+ string.find('//h1')[:data].should == 'fantastic'
57
+ end
58
+
59
+ it "allows finding elements and extracting the tag name from them" do
60
+ string.find('//h1').tag_name.should == 'h1'
61
+ end
62
+
63
+ it "allows finding elements and extracting the path" do
64
+ string.find('//h1').path.should == '/html/body/div/div[1]/h1'
65
+ end
66
+
67
+ it "allows finding elements and extracting the path" do
68
+ string.find('//input').value.should == 'bar'
69
+ string.find('//select').value.should == 'Capybara'
70
+ end
71
+
72
+ it "allows finding elements and checking if they are visible" do
73
+ string.find('//h1').should be_visible
74
+ string.find('//input').should_not be_visible
75
+ end
76
+ end
77
+ end