capybara 0.3.9 → 0.4.0.rc

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 (70) hide show
  1. data/History.txt +43 -1
  2. data/README.rdoc +168 -98
  3. data/lib/capybara.rb +77 -15
  4. data/lib/capybara/driver/base.rb +21 -16
  5. data/lib/capybara/driver/celerity_driver.rb +39 -41
  6. data/lib/capybara/driver/culerity_driver.rb +2 -1
  7. data/lib/capybara/driver/node.rb +66 -0
  8. data/lib/capybara/driver/rack_test_driver.rb +66 -67
  9. data/lib/capybara/driver/selenium_driver.rb +43 -47
  10. data/lib/capybara/dsl.rb +44 -6
  11. data/lib/capybara/node.rb +185 -24
  12. data/lib/capybara/node/actions.rb +170 -0
  13. data/lib/capybara/node/finders.rb +150 -0
  14. data/lib/capybara/node/matchers.rb +360 -0
  15. data/lib/capybara/rails.rb +1 -0
  16. data/lib/capybara/selector.rb +52 -0
  17. data/lib/capybara/server.rb +68 -87
  18. data/lib/capybara/session.rb +221 -207
  19. data/lib/capybara/spec/driver.rb +45 -35
  20. data/lib/capybara/spec/public/test.js +1 -1
  21. data/lib/capybara/spec/session.rb +28 -53
  22. data/lib/capybara/spec/session/all_spec.rb +7 -3
  23. data/lib/capybara/spec/session/check_spec.rb +50 -52
  24. data/lib/capybara/spec/session/click_button_spec.rb +9 -0
  25. data/lib/capybara/spec/session/click_link_or_button_spec.rb +37 -0
  26. data/lib/capybara/spec/session/current_url_spec.rb +7 -0
  27. data/lib/capybara/spec/session/find_button_spec.rb +4 -2
  28. data/lib/capybara/spec/session/find_by_id_spec.rb +4 -2
  29. data/lib/capybara/spec/session/find_field_spec.rb +7 -3
  30. data/lib/capybara/spec/session/find_link_spec.rb +5 -3
  31. data/lib/capybara/spec/session/find_spec.rb +71 -6
  32. data/lib/capybara/spec/session/has_field_spec.rb +1 -1
  33. data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
  34. data/lib/capybara/spec/session/has_xpath_spec.rb +4 -4
  35. data/lib/capybara/spec/session/javascript.rb +25 -5
  36. data/lib/capybara/spec/session/select_spec.rb +16 -2
  37. data/lib/capybara/spec/session/unselect_spec.rb +8 -1
  38. data/lib/capybara/spec/session/within_spec.rb +5 -5
  39. data/lib/capybara/spec/views/form.erb +65 -1
  40. data/lib/capybara/spec/views/popup_one.erb +8 -0
  41. data/lib/capybara/spec/views/popup_two.erb +8 -0
  42. data/lib/capybara/spec/views/with_html.erb +5 -0
  43. data/lib/capybara/spec/views/within_popups.erb +25 -0
  44. data/lib/capybara/{save_and_open_page.rb → util/save_and_open_page.rb} +3 -3
  45. data/lib/capybara/util/timeout.rb +27 -0
  46. data/lib/capybara/version.rb +1 -1
  47. data/spec/capybara_spec.rb +18 -8
  48. data/spec/driver/celerity_driver_spec.rb +10 -14
  49. data/spec/driver/culerity_driver_spec.rb +4 -3
  50. data/spec/driver/rack_test_driver_spec.rb +39 -2
  51. data/spec/driver/remote_culerity_driver_spec.rb +5 -7
  52. data/spec/driver/remote_selenium_driver_spec.rb +7 -10
  53. data/spec/driver/selenium_driver_spec.rb +3 -2
  54. data/spec/dsl_spec.rb +5 -14
  55. data/spec/save_and_open_page_spec.rb +19 -19
  56. data/spec/server_spec.rb +22 -10
  57. data/spec/session/celerity_session_spec.rb +17 -21
  58. data/spec/session/culerity_session_spec.rb +3 -3
  59. data/spec/session/rack_test_session_spec.rb +2 -2
  60. data/spec/session/selenium_session_spec.rb +2 -2
  61. data/spec/spec_helper.rb +27 -6
  62. data/spec/{wait_until_spec.rb → timeout_spec.rb} +14 -14
  63. metadata +88 -46
  64. data/lib/capybara/searchable.rb +0 -54
  65. data/lib/capybara/spec/session/click_spec.rb +0 -24
  66. data/lib/capybara/spec/session/locate_spec.rb +0 -65
  67. data/lib/capybara/wait_until.rb +0 -28
  68. data/lib/capybara/xpath.rb +0 -179
  69. data/spec/searchable_spec.rb +0 -66
  70. data/spec/xpath_spec.rb +0 -180
@@ -5,4 +5,11 @@ shared_examples_for "current_url" do
5
5
  @session.current_url.should =~ %r(http://[^/]+/form)
6
6
  end
7
7
  end
8
+
9
+ describe '#current_path' do
10
+ it 'should show the correct location' do
11
+ @session.visit('/foo')
12
+ @session.current_path.should == '/foo'
13
+ end
14
+ end
8
15
  end
@@ -9,8 +9,10 @@ shared_examples_for "find_button" do
9
9
  @session.find_button('crap321').value.should == "crappy"
10
10
  end
11
11
 
12
- it "should return nil if the field doesn't exist" do
13
- @session.find_button('Does not exist').should be_nil
12
+ it "should raise error if the field doesn't exist" do
13
+ running do
14
+ @session.find_button('Does not exist')
15
+ end.should raise_error(Capybara::ElementNotFound)
14
16
  end
15
17
  end
16
18
  end
@@ -9,8 +9,10 @@ shared_examples_for "find_by_id" do
9
9
  @session.find_by_id('hidden_via_ancestor').tag_name.should == 'div'
10
10
  end
11
11
 
12
- it "should return nil if no element with id is found" do
13
- @session.find_by_id('nothing_with_this_id').should be_nil
12
+ it "should raise error if no element with id is found" do
13
+ running do
14
+ @session.find_by_id('nothing_with_this_id')
15
+ end.should raise_error(Capybara::ElementNotFound)
14
16
  end
15
17
  end
16
18
  end
@@ -10,13 +10,17 @@ shared_examples_for "find_field" do
10
10
  @session.find_field('Region')[:name].should == 'form[region]'
11
11
  end
12
12
 
13
- it "should be nil if the field doesn't exist" do
14
- @session.find_field('Does not exist').should be_nil
13
+ it "should raise error if the field doesn't exist" do
14
+ running do
15
+ @session.find_field('Does not exist')
16
+ end.should raise_error(Capybara::ElementNotFound)
15
17
  end
16
18
 
17
19
  it "should be aliased as 'field_labeled' for webrat compatibility" do
18
20
  @session.field_labeled('Dog').value.should == 'dog'
19
- @session.field_labeled('Does not exist').should be_nil
21
+ running do
22
+ @session.field_labeled('Does not exist')
23
+ end.should raise_error(Capybara::ElementNotFound)
20
24
  end
21
25
  end
22
26
  end
@@ -7,11 +7,13 @@ shared_examples_for "find_link" do
7
7
 
8
8
  it "should find any field" do
9
9
  @session.find_link('foo').text.should == "ullamco"
10
- @session.find_link('labore')[:href].should == "/with_simple_html"
10
+ @session.find_link('labore')[:href].should =~ %r(/with_simple_html$)
11
11
  end
12
12
 
13
- it "should return nil if the field doesn't exist" do
14
- @session.find_link('Does not exist').should be_nil
13
+ it "should raise error if the field doesn't exist" do
14
+ running do
15
+ @session.find_link('Does not exist')
16
+ end.should raise_error(Capybara::ElementNotFound)
15
17
  end
16
18
  end
17
19
  end
@@ -1,14 +1,45 @@
1
- shared_examples_for "find" do
1
+ shared_examples_for "find" do
2
2
  describe '#find' do
3
3
  before do
4
4
  @session.visit('/with_html')
5
5
  end
6
6
 
7
+ after do
8
+ Capybara::Selector.remove(:monkey)
9
+ end
10
+
7
11
  it "should find the first element using the given locator" do
8
12
  @session.find('//h1').text.should == 'This is a test'
9
13
  @session.find("//input[@id='test_field']")[:value].should == 'monkey'
10
14
  end
11
15
 
16
+ it "should be aliased as locate for backward compatibility" do
17
+ Capybara.should_receive(:deprecate).with("locate", "find").twice
18
+ @session.locate('//h1').text.should == 'This is a test'
19
+ @session.locate("//input[@id='test_field']")[:value].should == 'monkey'
20
+ end
21
+
22
+ it "should find the first element using the given locator and options" do
23
+ @session.find('//a', :text => 'Redirect')[:id].should == 'red'
24
+ @session.find(:css, 'a', :text => 'A link')[:title].should == 'twas a fine link'
25
+ end
26
+
27
+ describe 'the returned node' do
28
+ it "should act like a session object" do
29
+ @session.visit('/form')
30
+ @form = @session.find(:css, '#get-form')
31
+ @form.should have_field('Middle Name')
32
+ @form.should have_no_field('Languages')
33
+ @form.fill_in('Middle Name', :with => 'Monkey')
34
+ @form.click_button('med')
35
+ extract_results(@session)['middle_name'].should == 'Monkey'
36
+ end
37
+
38
+ it "should scope CSS selectors" do
39
+ @session.find(:css, '#second').should have_no_css('h1')
40
+ end
41
+ end
42
+
12
43
  context "with css selectors" do
13
44
  it "should find the first element using the given locator" do
14
45
  @session.find(:css, 'h1').text.should == 'This is a test'
@@ -16,6 +47,14 @@ shared_examples_for "find" do
16
47
  end
17
48
  end
18
49
 
50
+ context "with id selectors" do
51
+ it "should find the first element using the given locator" do
52
+ @session.find(:id, 'john_monkey').text.should == 'Monkey John'
53
+ @session.find(:id, 'red').text.should == 'Redirect'
54
+ @session.find(:red).text.should == 'Redirect'
55
+ end
56
+ end
57
+
19
58
  context "with xpath selectors" do
20
59
  it "should find the first element using the given locator" do
21
60
  @session.find(:xpath, '//h1').text.should == 'This is a test'
@@ -23,6 +62,24 @@ shared_examples_for "find" do
23
62
  end
24
63
  end
25
64
 
65
+ context "with custom selector" do
66
+ it "should use the custom selector" do
67
+ Capybara::Selector.add(:monkey) { |name| ".//*[@id='#{name}_monkey']" }
68
+ @session.find(:monkey, 'john').text.should == 'Monkey John'
69
+ @session.find(:monkey, 'paul').text.should == 'Monkey Paul'
70
+ end
71
+ end
72
+
73
+ context "with custom selector with :for option" do
74
+ it "should use the selector when it matches the :for option" do
75
+ Capybara::Selector.add(:monkey, :for => Fixnum) { |num| ".//*[contains(@id, 'monkey')][#{num}]" }
76
+ @session.find(:monkey, '2').text.should == 'Monkey Paul'
77
+ @session.find(1).text.should == 'Monkey John'
78
+ @session.find(2).text.should == 'Monkey Paul'
79
+ @session.find('//h1').text.should == 'This is a test'
80
+ end
81
+ end
82
+
26
83
  context "with css as default selector" do
27
84
  before { Capybara.default_selector = :css }
28
85
  it "should find the first element using the given locator" do
@@ -32,13 +89,21 @@ shared_examples_for "find" do
32
89
  after { Capybara.default_selector = :xpath }
33
90
  end
34
91
 
35
- it "should return nil when nothing was found" do
36
- @session.find('//div[@id="nosuchthing"]').should be_nil
92
+ it "should raise ElementNotFound with specified fail message if nothing was found" do
93
+ running do
94
+ @session.find(:xpath, '//div[@id="nosuchthing"]', :message => 'arghh').should be_nil
95
+ end.should raise_error(Capybara::ElementNotFound, "arghh")
96
+ end
97
+
98
+ it "should raise ElementNotFound with a useful default message if nothing was found" do
99
+ running do
100
+ @session.find(:xpath, '//div[@id="nosuchthing"]').should be_nil
101
+ end.should raise_error(Capybara::ElementNotFound, "Unable to find '//div[@id=\"nosuchthing\"]'")
37
102
  end
38
103
 
39
104
  it "should accept an XPath instance and respect the order of paths" do
40
105
  @session.visit('/form')
41
- @xpath = Capybara::XPath.text_field('Name')
106
+ @xpath = XPath::HTML.fillable_field('Name')
42
107
  @session.find(@xpath).value.should == 'John Smith'
43
108
  end
44
109
 
@@ -49,8 +114,8 @@ shared_examples_for "find" do
49
114
 
50
115
  it "should find the first element using the given locator" do
51
116
  @session.within(:xpath, "//div[@id='for_bar']") do
52
- @session.find('//li').text.should =~ /With Simple HTML/
53
- end
117
+ @session.find('.//li').text.should =~ /With Simple HTML/
118
+ end
54
119
  end
55
120
  end
56
121
  end
@@ -42,7 +42,7 @@ shared_examples_for "has_field" do
42
42
  end
43
43
 
44
44
  context 'with value' do
45
- it "should be flase if a field with the given value is on the page" do
45
+ it "should be false if a field with the given value is on the page" do
46
46
  @session.should_not have_no_field('First Name', :with => 'John')
47
47
  @session.should_not have_no_field('Phone', :with => '+1 555 7021')
48
48
  @session.should_not have_no_field('Street', :with => 'Sesame street 66')
@@ -0,0 +1,129 @@
1
+ shared_examples_for "has_selector" do
2
+ describe '#has_selector?' do
3
+ before do
4
+ @session.visit('/with_html')
5
+ end
6
+
7
+ it "should be true if the given selector is on the page" do
8
+ @session.should have_selector(:xpath, "//p")
9
+ @session.should have_selector(:css, "p a#foo")
10
+ @session.should have_selector(:foo)
11
+ @session.should have_selector("//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_selector(:xpath, "//abbr")
16
+ @session.should_not have_selector(:css, "p a#doesnotexist")
17
+ @session.should_not have_selector(:doesnotexist)
18
+ @session.should_not have_selector("//p[contains(.,'thisstringisnotonpage')]")
19
+ end
20
+
21
+ it "should use default selector" do
22
+ Capybara.default_selector = :css
23
+ @session.should_not have_selector("p a#doesnotexist")
24
+ @session.should have_selector("p a#foo")
25
+ end
26
+
27
+ it "should respect scopes" do
28
+ @session.within "//p[@id='first']" do
29
+ @session.should have_selector(".//a[@id='foo']")
30
+ @session.should_not have_selector(".//a[@id='red']")
31
+ end
32
+ end
33
+
34
+ context "with count" do
35
+ it "should be true if the content is on the page the given number of times" do
36
+ @session.should have_selector("//p", :count => 3)
37
+ @session.should have_selector("//p//a[@id='foo']", :count => 1)
38
+ @session.should have_selector("//p[contains(.,'est')]", :count => 1)
39
+ end
40
+
41
+ it "should be false if the content is on the page the given number of times" do
42
+ @session.should_not have_selector("//p", :count => 6)
43
+ @session.should_not have_selector("//p//a[@id='foo']", :count => 2)
44
+ @session.should_not have_selector("//p[contains(.,'est')]", :count => 5)
45
+ end
46
+
47
+ it "should be false if the content isn't on the page at all" do
48
+ @session.should_not have_selector("//abbr", :count => 2)
49
+ @session.should_not have_selector("//p//a[@id='doesnotexist']", :count => 1)
50
+ end
51
+ end
52
+
53
+ context "with text" do
54
+ it "should discard all matches where the given string is not contained" do
55
+ @session.should have_selector("//p//a", :text => "Redirect", :count => 1)
56
+ @session.should_not have_selector("//p", :text => "Doesnotexist")
57
+ end
58
+
59
+ it "should discard all matches where the given regexp is not matched" do
60
+ @session.should have_selector("//p//a", :text => /re[dab]i/i, :count => 1)
61
+ @session.should_not have_selector("//p//a", :text => /Red$/)
62
+ end
63
+ end
64
+ end
65
+
66
+ describe '#has_no_selector?' do
67
+ before do
68
+ @session.visit('/with_html')
69
+ end
70
+
71
+ it "should be false if the given selector is on the page" do
72
+ @session.should_not have_no_selector(:xpath, "//p")
73
+ @session.should_not have_no_selector(:css, "p a#foo")
74
+ @session.should_not have_no_selector(:foo)
75
+ @session.should_not have_no_selector("//p[contains(.,'est')]")
76
+ end
77
+
78
+ it "should be true if the given selector is not on the page" do
79
+ @session.should have_no_selector(:xpath, "//abbr")
80
+ @session.should have_no_selector(:css, "p a#doesnotexist")
81
+ @session.should have_no_selector(:doesnotexist)
82
+ @session.should have_no_selector("//p[contains(.,'thisstringisnotonpage')]")
83
+ end
84
+
85
+ it "should use default selector" do
86
+ Capybara.default_selector = :css
87
+ @session.should have_no_selector("p a#doesnotexist")
88
+ @session.should_not have_no_selector("p a#foo")
89
+ end
90
+
91
+ it "should respect scopes" do
92
+ @session.within "//p[@id='first']" do
93
+ @session.should_not have_no_selector(".//a[@id='foo']")
94
+ @session.should have_no_selector(".//a[@id='red']")
95
+ end
96
+ end
97
+
98
+ context "with count" do
99
+ it "should be false if the content is on the page the given number of times" do
100
+ @session.should_not have_no_selector("//p", :count => 3)
101
+ @session.should_not have_no_selector("//p//a[@id='foo']", :count => 1)
102
+ @session.should_not have_no_selector("//p[contains(.,'est')]", :count => 1)
103
+ end
104
+
105
+ it "should be true if the content is on the page the wrong number of times" do
106
+ @session.should have_no_selector("//p", :count => 6)
107
+ @session.should have_no_selector("//p//a[@id='foo']", :count => 2)
108
+ @session.should have_no_selector("//p[contains(.,'est')]", :count => 5)
109
+ end
110
+
111
+ it "should be true if the content isn't on the page at all" do
112
+ @session.should have_no_selector("//abbr", :count => 2)
113
+ @session.should have_no_selector("//p//a[@id='doesnotexist']", :count => 1)
114
+ end
115
+ end
116
+
117
+ context "with text" do
118
+ it "should discard all matches where the given string is contained" do
119
+ @session.should_not have_no_selector("//p//a", :text => "Redirect", :count => 1)
120
+ @session.should have_no_selector("//p", :text => "Doesnotexist")
121
+ end
122
+
123
+ it "should discard all matches where the given regexp is matched" do
124
+ @session.should_not have_no_selector("//p//a", :text => /re[dab]i/i, :count => 1)
125
+ @session.should have_no_selector("//p//a", :text => /Red$/)
126
+ end
127
+ end
128
+ end
129
+ end
@@ -23,8 +23,8 @@ shared_examples_for "has_xpath" do
23
23
 
24
24
  it "should respect scopes" do
25
25
  @session.within "//p[@id='first']" do
26
- @session.should have_xpath("//a[@id='foo']")
27
- @session.should_not have_xpath("//a[@id='red']")
26
+ @session.should have_xpath(".//a[@id='foo']")
27
+ @session.should_not have_xpath(".//a[@id='red']")
28
28
  end
29
29
  end
30
30
 
@@ -84,8 +84,8 @@ shared_examples_for "has_xpath" do
84
84
 
85
85
  it "should respect scopes" do
86
86
  @session.within "//p[@id='first']" do
87
- @session.should_not have_no_xpath("//a[@id='foo']")
88
- @session.should have_no_xpath("//a[@id='red']")
87
+ @session.should_not have_no_xpath(".//a[@id='foo']")
88
+ @session.should have_no_xpath(".//a[@id='red']")
89
89
  end
90
90
  end
91
91
 
@@ -7,6 +7,26 @@ shared_examples_for "session with javascript support" do
7
7
  after do
8
8
  Capybara.default_wait_time = 0
9
9
  end
10
+
11
+ describe '#drag' do
12
+ it "should drag and drop an object" do
13
+ pending "drag/drop is currently broken under celerity/culerity" if @session.driver.is_a?(Capybara::Driver::Celerity)
14
+ @session.visit('/with_js')
15
+ @session.drag('//div[@id="drag"]', '//div[@id="drop"]')
16
+ @session.find('//div[contains(., "Dropped!")]').should_not be_nil
17
+ end
18
+ end
19
+
20
+ describe 'Node#drag_to' do
21
+ it "should drag and drop an object" do
22
+ pending "drag/drop is currently broken under celerity/culerity" if @session.driver.is_a?(Capybara::Driver::Celerity)
23
+ @session.visit('/with_js')
24
+ element = @session.find('//div[@id="drag"]')
25
+ target = @session.find('//div[@id="drop"]')
26
+ element.drag_to(target)
27
+ @session.find('//div[contains(., "Dropped!")]').should_not be_nil
28
+ end
29
+ end
10
30
 
11
31
  describe '#find' do
12
32
  it "should allow triggering of custom JS events" do
@@ -49,11 +69,11 @@ shared_examples_for "session with javascript support" do
49
69
  end
50
70
  end
51
71
 
52
- describe '#locate' do
72
+ describe '#find' do
53
73
  it "should wait for asynchronous load" do
54
74
  @session.visit('/with_js')
55
75
  @session.click_link('Click me')
56
- @session.locate("//a[contains(.,'Has been clicked')]")[:href].should == '#'
76
+ @session.find(:css, "a#has-been-clicked").text.should include('Has been clicked')
57
77
  end
58
78
  end
59
79
 
@@ -80,7 +100,7 @@ shared_examples_for "session with javascript support" do
80
100
  @session.visit('/with_html')
81
101
  Proc.new do
82
102
  @session.wait_until(0.1) do
83
- @session.find('//div[@id="nosuchthing"]')
103
+ @session.all('//div[@id="nosuchthing"]').first
84
104
  end
85
105
  end.should raise_error(::Capybara::TimeoutError)
86
106
  end
@@ -109,11 +129,11 @@ shared_examples_for "session with javascript support" do
109
129
  end
110
130
  end
111
131
 
112
- describe '#click' do
132
+ describe '#click_link_or_button' do
113
133
  it "should wait for asynchronous load" do
114
134
  @session.visit('/with_js')
115
135
  @session.click_link('Click me')
116
- @session.click('Has been clicked')
136
+ @session.click_link_or_button('Has been clicked')
117
137
  end
118
138
  end
119
139
 
@@ -3,7 +3,7 @@ shared_examples_for "select" do
3
3
  before do
4
4
  @session.visit('/form')
5
5
  end
6
-
6
+
7
7
  it "should return value of the first option" do
8
8
  @session.find_field('Title').value.should == 'Mrs'
9
9
  end
@@ -13,6 +13,10 @@ shared_examples_for "select" do
13
13
  @session.find_field('Title').value.should == 'Miss'
14
14
  end
15
15
 
16
+ it "should return the value attribute rather than content if present" do
17
+ @session.find_field('Locale').value.should == 'en'
18
+ end
19
+
16
20
  it "should select an option from a select box by id" do
17
21
  @session.select("Finish", :from => 'form_locale')
18
22
  @session.click_button('awesome')
@@ -25,6 +29,12 @@ shared_examples_for "select" do
25
29
  extract_results(@session)['locale'].should == 'fi'
26
30
  end
27
31
 
32
+ it "should select an option without giving a select box" do
33
+ @session.select("Mr")
34
+ @session.click_button('awesome')
35
+ extract_results(@session)['title'].should == 'Mr'
36
+ end
37
+
28
38
  it "should favour exact matches to option labels" do
29
39
  @session.select("Mr", :from => 'Title')
30
40
  @session.click_button('awesome')
@@ -59,7 +69,7 @@ shared_examples_for "select" do
59
69
 
60
70
  context "with an option that doesn't exist" do
61
71
  it "should raise an error" do
62
- running { @session.select('Does not Exist', :from => 'form_locale') }.should raise_error(Capybara::OptionNotFound)
72
+ running { @session.select('Does not Exist', :from => 'form_locale') }.should raise_error(Capybara::ElementNotFound)
63
73
  end
64
74
  end
65
75
 
@@ -86,6 +96,10 @@ shared_examples_for "select" do
86
96
  @session.click_button('awesome')
87
97
  extract_results(@session)['languages'].should include('Ruby', 'Javascript')
88
98
  end
99
+
100
+ it "should return value attribute rather than content if present" do
101
+ @session.find_field('Underwear').value.should include('thermal')
102
+ end
89
103
  end
90
104
  end
91
105
  end