capybara 0.2.0 → 0.3.0

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 (71) hide show
  1. data/Manifest.txt +39 -0
  2. data/README.rdoc +181 -57
  3. data/Rakefile +7 -16
  4. data/config.ru +6 -0
  5. data/lib/capybara.rb +19 -9
  6. data/lib/capybara/cucumber.rb +4 -0
  7. data/lib/capybara/driver/base.rb +25 -8
  8. data/lib/capybara/driver/celerity_driver.rb +108 -0
  9. data/lib/capybara/driver/culerity_driver.rb +1 -70
  10. data/lib/capybara/driver/rack_test_driver.rb +57 -25
  11. data/lib/capybara/driver/selenium_driver.rb +28 -10
  12. data/lib/capybara/dsl.rb +7 -4
  13. data/lib/capybara/node.rb +50 -29
  14. data/lib/capybara/rails.rb +1 -1
  15. data/lib/capybara/save_and_open_page.rb +1 -1
  16. data/lib/capybara/searchable.rb +45 -0
  17. data/lib/capybara/server.rb +11 -4
  18. data/lib/capybara/session.rb +94 -94
  19. data/lib/capybara/wait_until.rb +23 -0
  20. data/lib/capybara/xpath.rb +55 -41
  21. data/spec/capybara_spec.rb +18 -0
  22. data/spec/driver/celerity_driver_spec.rb +17 -0
  23. data/spec/driver/culerity_driver_spec.rb +3 -0
  24. data/spec/driver/rack_test_driver_spec.rb +3 -0
  25. data/spec/driver/remote_culerity_driver_spec.rb +19 -0
  26. data/spec/driver/remote_selenium_driver_spec.rb +18 -0
  27. data/spec/driver/selenium_driver_spec.rb +2 -0
  28. data/spec/drivers_spec.rb +51 -5
  29. data/spec/dsl/all_spec.rb +38 -0
  30. data/spec/dsl/attach_file_spec.rb +66 -0
  31. data/spec/dsl/check_spec.rb +28 -0
  32. data/spec/dsl/choose_spec.rb +28 -0
  33. data/spec/dsl/click_button_spec.rb +183 -0
  34. data/spec/dsl/click_link_spec.rb +88 -0
  35. data/spec/dsl/click_spec.rb +26 -0
  36. data/spec/dsl/current_url_spec.rb +10 -0
  37. data/spec/dsl/fill_in_spec.rb +83 -0
  38. data/spec/dsl/find_button_spec.rb +18 -0
  39. data/spec/dsl/find_field_spec.rb +24 -0
  40. data/spec/dsl/find_link_spec.rb +19 -0
  41. data/spec/dsl/find_spec.rb +36 -0
  42. data/spec/dsl/has_content_spec.rb +103 -0
  43. data/spec/dsl/has_css_spec.rb +109 -0
  44. data/spec/dsl/has_xpath_spec.rb +115 -0
  45. data/spec/dsl/locate_spec.rb +38 -0
  46. data/spec/dsl/select_spec.rb +27 -0
  47. data/spec/dsl/uncheck_spec.rb +29 -0
  48. data/spec/dsl/within_spec.rb +145 -0
  49. data/spec/fixtures/capybara.jpg +0 -0
  50. data/spec/public/test.js +27 -0
  51. data/spec/searchable_spec.rb +61 -0
  52. data/spec/server_spec.rb +47 -0
  53. data/spec/session/celerity_session_spec.rb +27 -0
  54. data/spec/session/culerity_session_spec.rb +1 -0
  55. data/spec/session/rack_test_session_spec.rb +1 -0
  56. data/spec/session/selenium_session_spec.rb +1 -0
  57. data/spec/session_spec.rb +32 -903
  58. data/spec/session_with_headers_support_spec.rb +13 -0
  59. data/spec/session_with_javascript_support_spec.rb +165 -0
  60. data/spec/session_without_headers_support_spec.rb +15 -0
  61. data/spec/session_without_javascript_support_spec.rb +15 -0
  62. data/spec/spec_helper.rb +12 -0
  63. data/spec/test_app.rb +9 -1
  64. data/spec/views/form.erb +38 -0
  65. data/spec/views/postback.erb +13 -0
  66. data/spec/views/with_html.erb +13 -0
  67. data/spec/views/with_js.erb +9 -24
  68. data/spec/views/with_simple_html.erb +1 -1
  69. data/spec/wait_until_spec.rb +28 -0
  70. data/spec/xpath_spec.rb +34 -3
  71. metadata +54 -5
@@ -0,0 +1,18 @@
1
+ module FindButtonSpec
2
+ shared_examples_for "find_button" do
3
+ describe '#find_button' do
4
+ before do
5
+ @session.visit('/form')
6
+ end
7
+
8
+ it "should find any field" do
9
+ @session.find_button('med')[:id].should == "mediocre"
10
+ @session.find_button('crap321').value.should == "crappy"
11
+ end
12
+
13
+ it "should return nil if the field doesn't exist" do
14
+ @session.find_button('Does not exist').should be_nil
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ module FindFieldSpec
2
+ shared_examples_for "find_field" do
3
+ describe '#find_field' do
4
+ before do
5
+ @session.visit('/form')
6
+ end
7
+
8
+ it "should find any field" do
9
+ @session.find_field('Dog').value.should == 'dog'
10
+ @session.find_field('form_description').text.should == 'Descriptive text goes here'
11
+ @session.find_field('Region')[:name].should == 'form[region]'
12
+ end
13
+
14
+ it "should be nil if the field doesn't exist" do
15
+ @session.find_field('Does not exist').should be_nil
16
+ end
17
+
18
+ it "should be aliased as 'field_labeled' for webrat compatibility" do
19
+ @session.field_labeled('Dog').value.should == 'dog'
20
+ @session.field_labeled('Does not exist').should be_nil
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ module FindLinkSpec
2
+ shared_examples_for "find_link" do
3
+
4
+ describe '#find_link' do
5
+ before do
6
+ @session.visit('/with_html')
7
+ end
8
+
9
+ it "should find any field" do
10
+ @session.find_link('foo').text.should == "ullamco"
11
+ @session.find_link('labore')[:href].should == "/with_simple_html"
12
+ end
13
+
14
+ it "should return nil if the field doesn't exist" do
15
+ @session.find_link('Does not exist').should be_nil
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ module FindSpec
2
+ shared_examples_for "find" do
3
+ describe '#find' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it "should find the first element using the given locator" do
9
+ @session.find('//h1').text.should == 'This is a test'
10
+ @session.find("//input[@id='test_field']")[:value].should == 'monkey'
11
+ end
12
+
13
+ it "should return nil when nothing was found" do
14
+ @session.find('//div[@id="nosuchthing"]').should be_nil
15
+ end
16
+
17
+ it "should accept an XPath instance and respect the order of paths" do
18
+ @session.visit('/form')
19
+ @xpath = Capybara::XPath.text_field('Name')
20
+ @session.find(@xpath).value.should == 'John Smith'
21
+ end
22
+
23
+ context "within a scope" do
24
+ before do
25
+ @session.visit('/with_scope')
26
+ end
27
+
28
+ it "should find the first element using the given locator" do
29
+ @session.within(:xpath, "//div[@id='for_bar']") do
30
+ @session.find('//li').text.should =~ /With Simple HTML/
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,103 @@
1
+ module HasContentSpec
2
+ shared_examples_for "has_content" do
3
+ describe '#has_content?' do
4
+ it "should be true if the given content is on the page at least once" do
5
+ @session.visit('/with_html')
6
+ @session.should have_content('est')
7
+ @session.should have_content('Lorem')
8
+ @session.should have_content('Redirect')
9
+ end
10
+
11
+ it "should be true if scoped to an element which has the content" do
12
+ @session.visit('/with_html')
13
+ @session.within("//a[@title='awesome title']") do
14
+ @session.should have_content('labore')
15
+ end
16
+ end
17
+
18
+ it "should be false if scoped to an element which does not have the content" do
19
+ @session.visit('/with_html')
20
+ @session.within("//a[@title='awesome title']") do
21
+ @session.should_not have_content('monkey')
22
+ end
23
+ end
24
+
25
+ it "should ignore tags" do
26
+ @session.visit('/with_html')
27
+ @session.should_not have_content('exercitation <a href="/foo" id="foo">ullamco</a> laboris')
28
+ @session.should have_content('exercitation ullamco laboris')
29
+ end
30
+
31
+ it "should be false if the given content is not on the page" do
32
+ @session.visit('/with_html')
33
+ @session.should_not have_content('xxxxyzzz')
34
+ @session.should_not have_content('monkey')
35
+ end
36
+
37
+ it 'should handle single quotes in the content' do
38
+ @session.visit('/with-quotes')
39
+ @session.should have_content("can't")
40
+ end
41
+
42
+ it 'should handle double quotes in the content' do
43
+ @session.visit('/with-quotes')
44
+ @session.should have_content(%q{"No," he said})
45
+ end
46
+
47
+ it 'should handle mixed single and double quotes in the content' do
48
+ @session.visit('/with-quotes')
49
+ @session.should have_content(%q{"you can't do that."})
50
+ end
51
+ end
52
+
53
+ describe '#has_no_content?' do
54
+ it "should be false if the given content is on the page at least once" do
55
+ @session.visit('/with_html')
56
+ @session.should_not have_no_content('est')
57
+ @session.should_not have_no_content('Lorem')
58
+ @session.should_not have_no_content('Redirect')
59
+ end
60
+
61
+ it "should be false if scoped to an element which has the content" do
62
+ @session.visit('/with_html')
63
+ @session.within("//a[@title='awesome title']") do
64
+ @session.should_not have_no_content('labore')
65
+ end
66
+ end
67
+
68
+ it "should be true if scoped to an element which does not have the content" do
69
+ @session.visit('/with_html')
70
+ @session.within("//a[@title='awesome title']") do
71
+ @session.should have_no_content('monkey')
72
+ end
73
+ end
74
+
75
+ it "should ignore tags" do
76
+ @session.visit('/with_html')
77
+ @session.should have_no_content('exercitation <a href="/foo" id="foo">ullamco</a> laboris')
78
+ @session.should_not have_no_content('exercitation ullamco laboris')
79
+ end
80
+
81
+ it "should be true if the given content is not on the page" do
82
+ @session.visit('/with_html')
83
+ @session.should have_no_content('xxxxyzzz')
84
+ @session.should have_no_content('monkey')
85
+ end
86
+
87
+ it 'should handle single quotes in the content' do
88
+ @session.visit('/with-quotes')
89
+ @session.should_not have_no_content("can't")
90
+ end
91
+
92
+ it 'should handle double quotes in the content' do
93
+ @session.visit('/with-quotes')
94
+ @session.should_not have_no_content(%q{"No," he said})
95
+ end
96
+
97
+ it 'should handle mixed single and double quotes in the content' do
98
+ @session.visit('/with-quotes')
99
+ @session.should_not have_no_content(%q{"you can't do that."})
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,109 @@
1
+ module HasCssSpec
2
+ shared_examples_for "has_css" do
3
+ describe '#has_css?' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it "should be true if the given selector is on the page" do
9
+ @session.should have_css("p")
10
+ @session.should have_css("p a#foo")
11
+ end
12
+
13
+ it "should be false if the given selector is not on the page" do
14
+ @session.should_not have_css("abbr")
15
+ @session.should_not have_css("p a#doesnotexist")
16
+ @session.should_not have_css("p.nosuchclass")
17
+ end
18
+
19
+ it "should respect scopes" do
20
+ @session.within "//p[@id='first']" do
21
+ @session.should have_css("a#foo")
22
+ @session.should_not have_css("a#red")
23
+ end
24
+ end
25
+
26
+ context "with count" do
27
+ it "should be true if the content is on the page the given number of times" do
28
+ @session.should have_css("p", :count => 3)
29
+ @session.should have_css("p a#foo", :count => 1)
30
+ end
31
+
32
+ it "should be false if the content is on the page the given number of times" do
33
+ @session.should_not have_css("p", :count => 6)
34
+ @session.should_not have_css("p a#foo", :count => 2)
35
+ end
36
+
37
+ it "should be false if the content isn't on the page at all" do
38
+ @session.should_not have_css("abbr", :count => 2)
39
+ @session.should_not have_css("p a.doesnotexist", :count => 1)
40
+ end
41
+ end
42
+
43
+ context "with text" do
44
+ it "should discard all matches where the given string is not contained" do
45
+ @session.should have_css("p a", :text => "Redirect", :count => 1)
46
+ @session.should_not have_css("p a", :text => "Doesnotexist")
47
+ end
48
+
49
+ it "should discard all matches where the given regexp is not matched" do
50
+ @session.should have_css("p a", :text => /re[dab]i/i, :count => 1)
51
+ @session.should_not have_css("p a", :text => /Red$/)
52
+ end
53
+ end
54
+ end
55
+
56
+ describe '#has_no_css?' do
57
+ before do
58
+ @session.visit('/with_html')
59
+ end
60
+
61
+ it "should be false if the given selector is on the page" do
62
+ @session.should_not have_no_css("p")
63
+ @session.should_not have_no_css("p a#foo")
64
+ end
65
+
66
+ it "should be true if the given selector is not on the page" do
67
+ @session.should have_no_css("abbr")
68
+ @session.should have_no_css("p a#doesnotexist")
69
+ @session.should have_no_css("p.nosuchclass")
70
+ end
71
+
72
+ it "should respect scopes" do
73
+ @session.within "//p[@id='first']" do
74
+ @session.should_not have_no_css("a#foo")
75
+ @session.should have_no_css("a#red")
76
+ end
77
+ end
78
+
79
+ context "with count" do
80
+ it "should be false if the content is on the page the given number of times" do
81
+ @session.should_not have_no_css("p", :count => 3)
82
+ @session.should_not have_no_css("p a#foo", :count => 1)
83
+ end
84
+
85
+ it "should be true if the content is on the page the given number of times" do
86
+ @session.should have_no_css("p", :count => 6)
87
+ @session.should have_no_css("p a#foo", :count => 2)
88
+ end
89
+
90
+ it "should be true if the content isn't on the page at all" do
91
+ @session.should have_no_css("abbr", :count => 2)
92
+ @session.should have_no_css("p a.doesnotexist", :count => 1)
93
+ end
94
+ end
95
+
96
+ context "with text" do
97
+ it "should discard all matches where the given string is not contained" do
98
+ @session.should_not have_no_css("p a", :text => "Redirect", :count => 1)
99
+ @session.should have_no_css("p a", :text => "Doesnotexist")
100
+ end
101
+
102
+ it "should discard all matches where the given regexp is not matched" do
103
+ @session.should_not have_no_css("p a", :text => /re[dab]i/i, :count => 1)
104
+ @session.should have_no_css("p a", :text => /Red$/)
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,115 @@
1
+ module HasXpathSpec
2
+ shared_examples_for "has_xpath" do
3
+ describe '#has_xpath?' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it "should be true if the given selector is on the page" do
9
+ @session.should have_xpath("//p")
10
+ @session.should have_xpath("//p//a[@id='foo']")
11
+ @session.should have_xpath("//p[contains(.,'est')]")
12
+ end
13
+
14
+ it "should be false if the given selector is not on the page" do
15
+ @session.should_not have_xpath("//abbr")
16
+ @session.should_not have_xpath("//p//a[@id='doesnotexist']")
17
+ @session.should_not have_xpath("//p[contains(.,'thisstringisnotonpage')]")
18
+ end
19
+
20
+ it "should respect scopes" do
21
+ @session.within "//p[@id='first']" do
22
+ @session.should have_xpath("//a[@id='foo']")
23
+ @session.should_not have_xpath("//a[@id='red']")
24
+ end
25
+ end
26
+
27
+ context "with count" do
28
+ it "should be true if the content is on the page the given number of times" do
29
+ @session.should have_xpath("//p", :count => 3)
30
+ @session.should have_xpath("//p//a[@id='foo']", :count => 1)
31
+ @session.should have_xpath("//p[contains(.,'est')]", :count => 1)
32
+ end
33
+
34
+ it "should be false if the content is on the page the given number of times" do
35
+ @session.should_not have_xpath("//p", :count => 6)
36
+ @session.should_not have_xpath("//p//a[@id='foo']", :count => 2)
37
+ @session.should_not have_xpath("//p[contains(.,'est')]", :count => 5)
38
+ end
39
+
40
+ it "should be false if the content isn't on the page at all" do
41
+ @session.should_not have_xpath("//abbr", :count => 2)
42
+ @session.should_not have_xpath("//p//a[@id='doesnotexist']", :count => 1)
43
+ end
44
+ end
45
+
46
+ context "with text" do
47
+ it "should discard all matches where the given string is not contained" do
48
+ @session.should have_xpath("//p//a", :text => "Redirect", :count => 1)
49
+ @session.should_not have_xpath("//p", :text => "Doesnotexist")
50
+ end
51
+
52
+ it "should discard all matches where the given regexp is not matched" do
53
+ @session.should have_xpath("//p//a", :text => /re[dab]i/i, :count => 1)
54
+ @session.should_not have_xpath("//p//a", :text => /Red$/)
55
+ end
56
+ end
57
+ end
58
+
59
+ describe '#has_no_xpath?' do
60
+ before do
61
+ @session.visit('/with_html')
62
+ end
63
+
64
+ it "should be false if the given selector is on the page" do
65
+ @session.should_not have_no_xpath("//p")
66
+ @session.should_not have_no_xpath("//p//a[@id='foo']")
67
+ @session.should_not have_no_xpath("//p[contains(.,'est')]")
68
+ end
69
+
70
+ it "should be true if the given selector is not on the page" do
71
+ @session.should have_no_xpath("//abbr")
72
+ @session.should have_no_xpath("//p//a[@id='doesnotexist']")
73
+ @session.should have_no_xpath("//p[contains(.,'thisstringisnotonpage')]")
74
+ end
75
+
76
+ it "should respect scopes" do
77
+ @session.within "//p[@id='first']" do
78
+ @session.should_not have_no_xpath("//a[@id='foo']")
79
+ @session.should have_no_xpath("//a[@id='red']")
80
+ end
81
+ end
82
+
83
+ context "with count" do
84
+ it "should be false if the content is on the page the given number of times" do
85
+ @session.should_not have_no_xpath("//p", :count => 3)
86
+ @session.should_not have_no_xpath("//p//a[@id='foo']", :count => 1)
87
+ @session.should_not have_no_xpath("//p[contains(.,'est')]", :count => 1)
88
+ end
89
+
90
+ it "should be true if the content is on the page the wrong number of times" do
91
+ @session.should have_no_xpath("//p", :count => 6)
92
+ @session.should have_no_xpath("//p//a[@id='foo']", :count => 2)
93
+ @session.should have_no_xpath("//p[contains(.,'est')]", :count => 5)
94
+ end
95
+
96
+ it "should be true if the content isn't on the page at all" do
97
+ @session.should have_no_xpath("//abbr", :count => 2)
98
+ @session.should have_no_xpath("//p//a[@id='doesnotexist']", :count => 1)
99
+ end
100
+ end
101
+
102
+ context "with text" do
103
+ it "should discard all matches where the given string is contained" do
104
+ @session.should_not have_no_xpath("//p//a", :text => "Redirect", :count => 1)
105
+ @session.should have_no_xpath("//p", :text => "Doesnotexist")
106
+ end
107
+
108
+ it "should discard all matches where the given regexp is matched" do
109
+ @session.should_not have_no_xpath("//p//a", :text => /re[dab]i/i, :count => 1)
110
+ @session.should have_no_xpath("//p//a", :text => /Red$/)
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,38 @@
1
+ module LocateSpec
2
+ shared_examples_for "locate" do
3
+ describe '#locate' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it "should find the first element using the given locator" do
9
+ @session.locate('//h1').text.should == 'This is a test'
10
+ @session.locate("//input[@id='test_field']")[:value].should == 'monkey'
11
+ end
12
+
13
+ it "should raise ElementNotFound with specified fail message if nothing was found" do
14
+ running do
15
+ @session.locate('//div[@id="nosuchthing"]', 'arghh').should be_nil
16
+ end.should raise_error(Capybara::ElementNotFound, "arghh")
17
+ end
18
+
19
+ it "should accept an XPath instance and respect the order of paths" do
20
+ @session.visit('/form')
21
+ @xpath = Capybara::XPath.text_field('Name')
22
+ @session.locate(@xpath).value.should == 'John Smith'
23
+ end
24
+
25
+ context "within a scope" do
26
+ before do
27
+ @session.visit('/with_scope')
28
+ end
29
+
30
+ it "should find the first element using the given locator" do
31
+ @session.within(:xpath, "//div[@id='for_bar']") do
32
+ @session.locate('//li').text.should =~ /With Simple HTML/
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end