bbc-capybara 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/History.txt +325 -0
  2. data/License.txt +22 -0
  3. data/README.md +815 -0
  4. data/lib/capybara.rb +368 -0
  5. data/lib/capybara/cucumber.rb +25 -0
  6. data/lib/capybara/driver/base.rb +64 -0
  7. data/lib/capybara/driver/node.rb +74 -0
  8. data/lib/capybara/dsl.rb +50 -0
  9. data/lib/capybara/node/actions.rb +146 -0
  10. data/lib/capybara/node/base.rb +63 -0
  11. data/lib/capybara/node/document.rb +25 -0
  12. data/lib/capybara/node/element.rb +201 -0
  13. data/lib/capybara/node/finders.rb +154 -0
  14. data/lib/capybara/node/matchers.rb +442 -0
  15. data/lib/capybara/node/simple.rb +132 -0
  16. data/lib/capybara/query.rb +63 -0
  17. data/lib/capybara/rack_test/browser.rb +126 -0
  18. data/lib/capybara/rack_test/driver.rb +80 -0
  19. data/lib/capybara/rack_test/form.rb +80 -0
  20. data/lib/capybara/rack_test/node.rb +121 -0
  21. data/lib/capybara/rails.rb +17 -0
  22. data/lib/capybara/rspec.rb +26 -0
  23. data/lib/capybara/rspec/features.rb +22 -0
  24. data/lib/capybara/rspec/matchers.rb +152 -0
  25. data/lib/capybara/selector.rb +156 -0
  26. data/lib/capybara/selenium/driver.rb +169 -0
  27. data/lib/capybara/selenium/node.rb +91 -0
  28. data/lib/capybara/server.rb +87 -0
  29. data/lib/capybara/session.rb +322 -0
  30. data/lib/capybara/spec/driver.rb +329 -0
  31. data/lib/capybara/spec/fixtures/capybara.jpg +3 -0
  32. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  33. data/lib/capybara/spec/public/jquery-ui.js +791 -0
  34. data/lib/capybara/spec/public/jquery.js +9046 -0
  35. data/lib/capybara/spec/public/test.js +43 -0
  36. data/lib/capybara/spec/session.rb +148 -0
  37. data/lib/capybara/spec/session/all_spec.rb +78 -0
  38. data/lib/capybara/spec/session/attach_file_spec.rb +76 -0
  39. data/lib/capybara/spec/session/check_spec.rb +68 -0
  40. data/lib/capybara/spec/session/choose_spec.rb +29 -0
  41. data/lib/capybara/spec/session/click_button_spec.rb +305 -0
  42. data/lib/capybara/spec/session/click_link_or_button_spec.rb +37 -0
  43. data/lib/capybara/spec/session/click_link_spec.rb +120 -0
  44. data/lib/capybara/spec/session/current_url_spec.rb +83 -0
  45. data/lib/capybara/spec/session/fill_in_spec.rb +127 -0
  46. data/lib/capybara/spec/session/find_button_spec.rb +18 -0
  47. data/lib/capybara/spec/session/find_by_id_spec.rb +18 -0
  48. data/lib/capybara/spec/session/find_field_spec.rb +26 -0
  49. data/lib/capybara/spec/session/find_link_spec.rb +19 -0
  50. data/lib/capybara/spec/session/find_spec.rb +168 -0
  51. data/lib/capybara/spec/session/first_spec.rb +105 -0
  52. data/lib/capybara/spec/session/has_button_spec.rb +32 -0
  53. data/lib/capybara/spec/session/has_css_spec.rb +243 -0
  54. data/lib/capybara/spec/session/has_field_spec.rb +192 -0
  55. data/lib/capybara/spec/session/has_link_spec.rb +37 -0
  56. data/lib/capybara/spec/session/has_select_spec.rb +129 -0
  57. data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
  58. data/lib/capybara/spec/session/has_table_spec.rb +34 -0
  59. data/lib/capybara/spec/session/has_text_spec.rb +138 -0
  60. data/lib/capybara/spec/session/has_xpath_spec.rb +123 -0
  61. data/lib/capybara/spec/session/headers.rb +19 -0
  62. data/lib/capybara/spec/session/javascript.rb +312 -0
  63. data/lib/capybara/spec/session/response_code.rb +19 -0
  64. data/lib/capybara/spec/session/select_spec.rb +119 -0
  65. data/lib/capybara/spec/session/text_spec.rb +24 -0
  66. data/lib/capybara/spec/session/uncheck_spec.rb +21 -0
  67. data/lib/capybara/spec/session/unselect_spec.rb +67 -0
  68. data/lib/capybara/spec/session/within_spec.rb +178 -0
  69. data/lib/capybara/spec/test_app.rb +156 -0
  70. data/lib/capybara/spec/views/buttons.erb +4 -0
  71. data/lib/capybara/spec/views/fieldsets.erb +29 -0
  72. data/lib/capybara/spec/views/form.erb +366 -0
  73. data/lib/capybara/spec/views/frame_one.erb +8 -0
  74. data/lib/capybara/spec/views/frame_two.erb +8 -0
  75. data/lib/capybara/spec/views/header_links.erb +7 -0
  76. data/lib/capybara/spec/views/host_links.erb +12 -0
  77. data/lib/capybara/spec/views/popup_one.erb +8 -0
  78. data/lib/capybara/spec/views/popup_two.erb +8 -0
  79. data/lib/capybara/spec/views/postback.erb +13 -0
  80. data/lib/capybara/spec/views/tables.erb +62 -0
  81. data/lib/capybara/spec/views/with_html.erb +75 -0
  82. data/lib/capybara/spec/views/with_html_entities.erb +1 -0
  83. data/lib/capybara/spec/views/with_js.erb +53 -0
  84. data/lib/capybara/spec/views/with_scope.erb +36 -0
  85. data/lib/capybara/spec/views/with_simple_html.erb +1 -0
  86. data/lib/capybara/spec/views/within_frames.erb +10 -0
  87. data/lib/capybara/spec/views/within_popups.erb +25 -0
  88. data/lib/capybara/util/save_and_open_page.rb +45 -0
  89. data/lib/capybara/util/timeout.rb +27 -0
  90. data/lib/capybara/version.rb +3 -0
  91. data/spec/basic_node_spec.rb +89 -0
  92. data/spec/capybara_spec.rb +46 -0
  93. data/spec/driver/rack_test_driver_spec.rb +90 -0
  94. data/spec/driver/selenium_driver_spec.rb +55 -0
  95. data/spec/dsl_spec.rb +255 -0
  96. data/spec/fixtures/selenium_driver_rspec_failure.rb +8 -0
  97. data/spec/fixtures/selenium_driver_rspec_success.rb +8 -0
  98. data/spec/rspec/features_spec.rb +43 -0
  99. data/spec/rspec/matchers_spec.rb +564 -0
  100. data/spec/rspec_spec.rb +51 -0
  101. data/spec/save_and_open_page_spec.rb +155 -0
  102. data/spec/server_spec.rb +74 -0
  103. data/spec/session/rack_test_session_spec.rb +61 -0
  104. data/spec/session/selenium_session_spec.rb +26 -0
  105. data/spec/spec_helper.rb +31 -0
  106. data/spec/timeout_spec.rb +28 -0
  107. metadata +297 -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,62 @@
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>
@@ -0,0 +1,75 @@
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>banana</textarea>
32
+ <a href="/redirect_back">BackToMyself</a>
33
+ <a title="twas a fine link" href="/redirect">A link came first</a>
34
+ <a title="a fine link" href="/with_simple_html">A link</a>
35
+ <a title="a fine link with data method" data-method="delete" href="/delete">A link with data-method</a>
36
+ <a title="a fine link with data method capitalized" data-method="DELETE" href="/delete">A link with data-method capitalized</a>
37
+ <a>No Href</a>
38
+ <a href="">Blank Href</a>
39
+ <a href="#">Blank Anchor</a>
40
+ <a href="#anchor">Anchor</a>
41
+ <a href="/with_simple_html#anchor">Anchor on different page</a>
42
+ <a href="/with_html#anchor">Anchor on same page</a>
43
+ <a href="with_html">Relative</a>
44
+ <input type="text" value="" id="test_field">
45
+ <input type="text" checked="checked" id="checked_field">
46
+ <a href="/redirect"><img width="20" height="20" alt="very fine image" /></a>
47
+ <a href="/with_simple_html"><img width="20" height="20" alt="fine image" /></a>
48
+
49
+ <a href="?query_string=true">Naked Query String</a>
50
+ <% if params[:query_string] %>
51
+ <em>Query String sent</em>
52
+ <% end %>
53
+ </p>
54
+
55
+ <div id="hidden" style="display: none;">
56
+ <div id="hidden_via_ancestor">Inside element with hidden ancestor</div>
57
+ <a href="/with_simple_html" title="awesome title" class="simple">hidden link</a>
58
+ </div>
59
+
60
+ <div style="display: none;">
61
+ <a id="first_invisble" class="hidden">first hidden link</a>
62
+ </div>
63
+
64
+ <div style="display: none;">
65
+ <a id="invisible" class="visibility hidden">hidden link</a>
66
+ </div>
67
+
68
+ <div>
69
+ <a id="visible" class="visibility">visible link</a>
70
+ </div>
71
+
72
+ <ul>
73
+ <li id="john_monkey">Monkey John</li>
74
+ <li id="paul_monkey">Monkey Paul</li>
75
+ </ul>
@@ -0,0 +1 @@
1
+ Encoding with &mdash; html entities &raquo;
@@ -0,0 +1,53 @@
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="/jquery.js" type="text/javascript" charset="utf-8"></script>
6
+ <script src="/jquery-ui.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
+
47
+ <script type="text/javascript">
48
+ // a javascript comment
49
+ var aVar = 123;
50
+ </script>
51
+ </body>
52
+ </html>
53
+
@@ -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,45 @@
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" # could raise LoadError
26
+ raise LoadError unless Launchy::Version::MAJOR >= 2
27
+ Launchy.open(path)
28
+ rescue LoadError
29
+ warn "Sorry, you need to install launchy >=2.0.0 (`gem install launchy`) and " <<
30
+ "make sure it's available to open pages with `save_and_open_page`."
31
+ end
32
+
33
+ def rewrite_css_and_image_references(response_html) # :nodoc:
34
+ root = Capybara.asset_root
35
+ return response_html unless root
36
+ directories = Dir.new(root).entries.select { |name|
37
+ (root+name).directory? and not name.to_s =~ /^\./
38
+ }
39
+ if not directories.empty?
40
+ response_html.gsub!(/("|')\/(#{directories.join('|')})/, '\1' + root.to_s + '/\2')
41
+ end
42
+ return response_html
43
+ end
44
+ end
45
+ 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,89 @@
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">Totally 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
+
23
+ <section>
24
+ <div class="subsection"></div>
25
+ </div>
26
+ </div>
27
+ STRING
28
+ end
29
+
30
+ it "allows using matchers" do
31
+ string.should have_css('#page')
32
+ string.should_not have_css('#does-not-exist')
33
+ end
34
+
35
+ it "allows using custom matchers" do
36
+ Capybara.add_selector :lifeform do
37
+ xpath { |name| "//option[contains(.,'#{name}')]" }
38
+ end
39
+ string.should have_selector(:page)
40
+ string.should_not have_selector(:'does-not-exist')
41
+ string.should have_selector(:lifeform, "Monkey")
42
+ string.should_not have_selector(:lifeform, "Gorilla")
43
+ end
44
+
45
+ it 'allows custom matcher using css' do
46
+ Capybara.add_selector :section do
47
+ css { |css_class| "section .#{css_class}" }
48
+ end
49
+ string.should have_selector(:section, 'subsection')
50
+ string.should_not have_selector(:section, 'section_8')
51
+ end
52
+
53
+ it "allows using matchers with text option" do
54
+ string.should have_css('h1', :text => 'Totally awesome')
55
+ string.should_not have_css('h1', :text => 'Not so awesome')
56
+ end
57
+
58
+ it "allows finding only visible nodes" do
59
+ string.all('//p', :text => 'c2010', :visible => true).should be_empty
60
+ string.all('//p', :text => 'c2010', :visible => false).should have(1).element
61
+ end
62
+
63
+ it "allows finding elements and extracting text from them" do
64
+ string.find('//h1').text.should == 'Totally awesome'
65
+ end
66
+
67
+ it "allows finding elements and extracting attributes from them" do
68
+ string.find('//h1')[:data].should == 'fantastic'
69
+ end
70
+
71
+ it "allows finding elements and extracting the tag name from them" do
72
+ string.find('//h1').tag_name.should == 'h1'
73
+ end
74
+
75
+ it "allows finding elements and extracting the path" do
76
+ string.find('//h1').path.should == '/html/body/div/div[1]/h1'
77
+ end
78
+
79
+ it "allows finding elements and extracting the path" do
80
+ string.find('//input').value.should == 'bar'
81
+ string.find('//select').value.should == 'Capybara'
82
+ end
83
+
84
+ it "allows finding elements and checking if they are visible" do
85
+ string.find('//h1').should be_visible
86
+ string.find('//input').should_not be_visible
87
+ end
88
+ end
89
+ end