marekj-watirloo 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/History.txt +12 -0
  2. data/Manifest.txt +59 -34
  3. data/README.rdoc +63 -80
  4. data/Rakefile.rb +32 -39
  5. data/config/locker.yml +0 -0
  6. data/lib/watirloo.rb +9 -162
  7. data/lib/watirloo/browsers.rb +73 -0
  8. data/lib/watirloo/desktop.rb +44 -0
  9. data/lib/watirloo/{firewatir_ducktape.rb → extension/firewatir_ducktape.rb} +0 -0
  10. data/lib/watirloo/extension/object.rb +26 -0
  11. data/lib/watirloo/{watir_ducktape.rb → extension/watir_ducktape.rb} +181 -16
  12. data/lib/watirloo/extension/watir_reflector.rb +83 -0
  13. data/lib/watirloo/locker.rb +84 -0
  14. data/lib/watirloo/page.rb +105 -0
  15. data/spec/browser_spec.rb +38 -0
  16. data/spec/browser_threads_spec.rb +45 -0
  17. data/spec/checkbox_group_spec.rb +136 -0
  18. data/spec/checkbox_groups_spec.rb +55 -0
  19. data/spec/checkboxes_value_spec.rb +35 -0
  20. data/spec/desktop_spec.rb +54 -0
  21. data/spec/extra/browser_events_spec.rb +76 -0
  22. data/spec/extra/page_objects_metrics.rb +139 -0
  23. data/spec/face_mixing_spec.rb +55 -0
  24. data/{test → spec}/firewatir/attach_instance_test.rb +0 -0
  25. data/spec/firewatir/spec_results.html +263 -0
  26. data/spec/firewatir/spec_results.txt +23 -0
  27. data/spec/firewatir/spec_results_failed.txt +3 -0
  28. data/{test → spec}/html/census.html +0 -0
  29. data/spec/html/checkbox_group1.html +33 -0
  30. data/spec/html/labels.html +53 -0
  31. data/spec/html/no_title.html +13 -0
  32. data/{test → spec}/html/person.html +0 -0
  33. data/spec/html/radio_group.html +35 -0
  34. data/{test → spec}/html/select_lists.html +0 -0
  35. data/spec/input_element_spec.rb +51 -0
  36. data/spec/label_spec.rb +65 -0
  37. data/spec/locker_spec.rb +49 -0
  38. data/spec/page_spec.rb +53 -0
  39. data/spec/person_def_wrappers_spec.rb +40 -0
  40. data/spec/radio_group_spec.rb +95 -0
  41. data/spec/radio_groups_spec.rb +55 -0
  42. data/spec/reflector_spec.rb +82 -0
  43. data/spec/select_list_options_spec.rb +40 -0
  44. data/spec/select_lists_spec.rb +151 -0
  45. data/{test/test_helper.rb → spec/spec_helper.rb} +6 -4
  46. data/spec/spec_helper_ff.rb +5 -0
  47. data/spec/spec_helper_runner.rb +13 -0
  48. data/spec/spec_results.html +566 -0
  49. data/spec/spec_results.txt +179 -0
  50. data/spec/spec_results_failed.txt +1 -0
  51. data/spec/text_fields_spec.rb +56 -0
  52. data/watirloo.gemspec +44 -44
  53. metadata +80 -39
  54. data/lib/watirloo/reflector.rb +0 -137
  55. data/test/checkbox_group_test.rb +0 -83
  56. data/test/checkboxes_value_test.rb +0 -50
  57. data/test/html/checkbox_group1.html +0 -20
  58. data/test/html/labels.html +0 -32
  59. data/test/html/radio_group.html +0 -41
  60. data/test/interfaces_test.rb +0 -79
  61. data/test/label_test.rb +0 -64
  62. data/test/person_def_wrappers_test.rb +0 -55
  63. data/test/radio_group_test.rb +0 -97
  64. data/test/select_list_in_class_test.rb +0 -39
  65. data/test/select_list_options_test.rb +0 -39
  66. data/test/select_lists_test.rb +0 -145
  67. data/test/text_fields_test.rb +0 -68
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe 'setting and getting values for individual checkboxes with value attributes in face definitions' do
4
+
5
+ # in watir you have to access each checkbox, we now have checkbox_group for this
6
+ # in Watirloo you can access CheckboxGroup as shortcut using
7
+ # :pets => [:checkbox_group, 'pets']
8
+ include Watirloo::Page
9
+ face(:pets_cat) { doc.checkbox(:name, 'pets', 'cat') }
10
+ face(:pets_dog) { doc.checkbox(:name, 'pets', 'dog') }
11
+ face(:pets_zook) { doc.checkbox(:name, 'pets', 'zook') }
12
+ face(:pets_zebra) { doc.checkbox(:name, 'pets', 'zebra') }
13
+ face(:pets_wumpa) { doc.checkbox(:name, 'pets', 'wumpa') }
14
+
15
+ before do
16
+ browser.goto testfile('checkbox_group1.html')
17
+ end
18
+
19
+ it 'semantic name accesses individual CheckBox' do
20
+ if browser.kind_of?(FireWatir::Firefox)
21
+ pets_cat.should be_kind_of(FireWatir::CheckBox)
22
+
23
+ elsif browser.kind_of?(Watir::IE)
24
+ pets_cat.should be_kind_of(Watir::CheckBox)
25
+ end
26
+ end
27
+
28
+ it 'set individual checkbox does not set other checkboxes sharing the same name' do
29
+ pets_dog.should_not be_checked
30
+ pets_dog.set true
31
+ pets_dog.should be_checked
32
+ pets_cat.should_not be_checked
33
+ end
34
+
35
+ end
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+
4
+ describe "Watirloo Desktop" do
5
+
6
+ it "clear closes all browsers on the desktop and browsers should be empty" do
7
+ Watirloo::Desktop.clear
8
+ Watirloo::Desktop.browsers.should be_empty
9
+ end
10
+
11
+ it "adding first browser should report 1 addition and no deletions" do
12
+ hwnds = Watirloo::Desktop.hwnds
13
+ Watir::IE.start
14
+ added = Watirloo::Desktop.additions(hwnds)
15
+ added.size.should == 1
16
+ Watirloo::Desktop.deletions(hwnds).should be_empty
17
+ end
18
+
19
+ it 'while one browser on the desktop the additions and deletions should be false' do
20
+ hwnds = Watirloo::Desktop.hwnds
21
+ hwnds.size.should == 1
22
+ Watirloo::Desktop.additions(hwnds).should be_empty
23
+ Watirloo::Desktop.deletions(hwnds).should be_empty
24
+ end
25
+
26
+ it 'adding second browser should report one addition and no deletions' do
27
+ hwnds = Watirloo::Desktop.hwnds
28
+ Watir::IE.start
29
+ Watirloo::Desktop.additions(hwnds).size.should == 1
30
+ Watirloo::Desktop.deletions(hwnds).should be_empty
31
+ Watirloo::Desktop.hwnds.size.should == 2
32
+ end
33
+
34
+ it 'close one should report 1 deletion and no additions, attempt to attach to deleted cause exception' do
35
+ hwnds = Watirloo::Desktop.hwnds
36
+ Watirloo::Desktop.browsers[0].close #close any
37
+ Watirloo::Desktop.additions(hwnds).should be_empty
38
+ deleted = Watirloo::Desktop.deletions(hwnds)
39
+ deleted.size.should == 1
40
+ lambda{ Watir::IE.attach :hwnd, deleted[0]}.should raise_error
41
+ end
42
+
43
+
44
+ it "close one and start new one should report one addition and one deletion" do
45
+ hwnds = Watirloo::Desktop.hwnds
46
+ hwnds.size.should == 1
47
+ Watir::IE.start
48
+ (Watir::IE.attach(:hwnd, hwnds[0])).close
49
+ sleep 5
50
+ Watirloo::Desktop.additions(hwnds).size.should == 1
51
+ Watirloo::Desktop.deletions(hwnds).size.should == 1
52
+ end
53
+
54
+ end
@@ -0,0 +1,76 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ require 'observer'
4
+
5
+ module Watirloo
6
+
7
+ # InternetExplorer Object DWebBrowserEvents2 is an Interface for Events.
8
+ # We can hook into the events and intercept the events we care to catch.
9
+ # Every time an event we care to watch for occurs the Publisher notifies observers.
10
+ # Extra: you can also build a publisher that listenes to 'HTMLDocumentEvents2' of ie.ie.document object
11
+ # and notify listeners to onclick events if you need to
12
+ # @events_to_publish = %w[BeforeNavigate2 DocumentComplete NavigateError NewWindow3]
13
+ class BrowserEventsPublisher
14
+
15
+ include Observable
16
+
17
+ def initialize( ie )
18
+ @events_to_publish = %w[BeforeNavigate2 DocumentComplete TitleChange NavigateError NewWindow3 OnQuit]
19
+ @event_sink = WIN32OLE_EVENT.new( ie.ie, 'DWebBrowserEvents2' )
20
+ end
21
+
22
+ def run
23
+ @events_to_publish.each do |event_name|
24
+ @event_sink.on_event(event_name) do |*args|
25
+ changed
26
+ notify_observers( event_name )
27
+ end
28
+ loop { WIN32OLE_EVENT.message_loop }
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ # Generic Observer of BrowserEventsPublisher.
35
+ # implements update method of an observer to be notified by publisher of events
36
+ class BrowserEventsListener
37
+ attr_accessor :events
38
+
39
+ def initialize( events_publisher )
40
+ events_publisher.add_observer self
41
+ @events = []
42
+ end
43
+
44
+ def update event_name
45
+ puts "#{Time.now}: #{event_name}"
46
+ @events << event_name
47
+ end
48
+ end
49
+ end
50
+
51
+
52
+
53
+
54
+ @ie = Watirloo.browser
55
+ events = Thread.start do
56
+ @publisher = Watirloo::BrowserEventsPublisher.new(@ie)
57
+ @publisher.run
58
+ end
59
+
60
+ @listener = Watirloo::BrowserEventsListener.new(@publisher)
61
+
62
+ puts "pub starter"
63
+ puts @listener.events.inspect
64
+
65
+ @ie.goto "http://yahoo.com/"
66
+ puts @listener.events.inspect
67
+
68
+ #sleep 60
69
+ @ie.goto "http://yahoo.com/"
70
+ puts @listener.events.inspect
71
+
72
+ #at_exit do
73
+ Thread.kill events
74
+ #end
75
+
76
+ #sleep 5
@@ -0,0 +1,139 @@
1
+ # see this;http://blog.jayfields.com/2008/02/ruby-dynamically-define-method.html
2
+ if VERSION <= '1.8.6'
3
+ class Object
4
+ module InstanceExecHelper; end
5
+ include InstanceExecHelper
6
+ # instance_exec method evaluates a block of code relative to the specified object, with parameters whom come from outside the object.
7
+ def instance_exec(*args, &block)
8
+ begin
9
+ old_critical, Thread.critical = Thread.critical, true
10
+ n = 0
11
+ n += 1 while respond_to?(mname="__instance_exec#{n}")
12
+ InstanceExecHelper.module_eval{ define_method(mname, &block) }
13
+ ensure
14
+ Thread.critical = old_critical
15
+ end
16
+ begin
17
+ ret = send(mname, *args)
18
+ ensure
19
+ InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil
20
+ end
21
+ ret
22
+ end
23
+ end
24
+ end
25
+
26
+ # Need to rethink this page adapter idea
27
+ # I can make shortcuts to page elements with either blocks or defs or some hashmaps.
28
+ # def is the easiest most versitile I think
29
+ #
30
+ # what does it buy me to have this mechanism for defining pageobjects?
31
+ # pageobject(:name) {browser.text_field(:name, 'somename')}
32
+ # The way someone works with tests is they will define code like this
33
+ # browser.text_field(:name, 'somename')
34
+ # Then you can wrap it as a proc and tag it with a name as above.
35
+ # on the other hand how about storing access to objects in yaml files?
36
+ #
37
+ # ---
38
+ # :bla:
39
+ # - :text_field
40
+ # - :name
41
+ # - bla
42
+ #
43
+ # ---
44
+ # object_name: bla
45
+ # - :text_field
46
+ # - :name
47
+ # - bla
48
+
49
+ #
50
+ #
51
+
52
+ require 'benchmark'
53
+ result = Benchmark.bmbm do |test|
54
+
55
+ test.report('class eval block') do
56
+ class PageByClassEval
57
+ def self.face(name, *args, &definition)
58
+ class_eval do
59
+ define_method(name) do |*args|
60
+ instance_exec(*args, &definition)
61
+ end
62
+ end
63
+ end
64
+ def browser
65
+ Watirloo.browser
66
+ end
67
+ face(:last_0) { browser.text_field(:name, "last_name0") }
68
+ #face(:last_arg) { |i| browser.text_field(:name, "last_name#{i}") }
69
+ end
70
+ 10000.times do
71
+ page = PageByClassEval.new
72
+ page.last_0.value
73
+ #page.last_arg(0).value
74
+ end
75
+ end
76
+
77
+ test.report('regular def') do
78
+ class PageByDef
79
+ def browser
80
+ Watirloo.browser
81
+ end
82
+ def last(cc="0")
83
+ browser.text_field(:name, "last_name#{cc}")
84
+ end
85
+ end
86
+ 10000.times do
87
+ page = PageByDef.new
88
+ page.last.value
89
+ #page.last(0).value
90
+ end
91
+ end
92
+
93
+
94
+ test.report('class eval string') do
95
+ class PageByClassEvalString
96
+ def browser
97
+ Watirloo.browser
98
+ end
99
+ def self.face(hash)
100
+ method_name = hash.keys[0]
101
+ watir_element, how, what = hash.values[0]
102
+ class_eval "def #{method_name}
103
+ browser.#{watir_element}(:#{how}, \"#{what}\")
104
+ end"
105
+
106
+ end
107
+ face :last => [:text_field, :name, "last_name0"]
108
+ end
109
+ 10000.times do
110
+ page = PageByClassEvalString.new
111
+ page.last.value
112
+ end
113
+ end
114
+
115
+
116
+
117
+ end
118
+
119
+
120
+ puts total = result.inject(0.0) { |mem, bm| mem + bm.real }
121
+ puts "total : " + total.to_s
122
+ puts "average: " + (total/result.size.to_f).to_s
123
+
124
+ =begin
125
+ Rehearsal -----------------------------------------------------
126
+ class eval block 4.344000 1.656000 6.000000 ( 14.656000)
127
+ regular def 3.781000 1.625000 5.406000 ( 13.344000)
128
+ class eval string 3.500000 1.531000 5.031000 ( 13.375000)
129
+ ------------------------------------------- total: 16.437000sec
130
+
131
+ user system total real
132
+ class eval block 4.422000 1.406000 5.828000 ( 13.953000)
133
+ regular def 3.313000 1.485000 4.798000 ( 13.344000)
134
+ class eval string 3.875000 1.171000 5.046000 ( 13.328000)
135
+ 40.6250002384186
136
+ total : 40.6250002384186
137
+ average: 13.5416667461395
138
+
139
+ =end
@@ -0,0 +1,55 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+
4
+ describe "Class client mixing interfaces from other modules" do
5
+
6
+ # Examples of Interface usage in Watirloo
7
+ # define interface to first and last name
8
+ module FullName
9
+ include Watirloo::Page
10
+ face(:first) {doc.text_field(:name, 'first_nm')}
11
+ face(:last) {doc.text_field(:name, 'last_nm')}
12
+ end
13
+
14
+ # this Address defines street name
15
+ module Address
16
+ include Watirloo::Page
17
+ face :street do
18
+ doc.text_field(:name, 'addr1')
19
+ end
20
+ end
21
+
22
+ # this page is a composition of interfaces that may appear by themselves
23
+ # as pages in an application.
24
+ # think of a Page as some container. It can be entire page or part of Page
25
+ # This page is composed of interfaces that appear in Address, FullName
26
+ # but become interface to PersonalInfo
27
+ # method face is shortcut for interface
28
+ class PersonalInfo
29
+ include Address
30
+ include FullName
31
+ include Watirloo::Page
32
+ face( :dob ) { doc.text_field(:name, 'dob') }
33
+ face( :gender ) { doc.select_list(:name, 'sex_cd') }
34
+ end
35
+
36
+
37
+ before :each do
38
+ @page = PersonalInfo.new
39
+ @page.browser.goto testfile('person.html')
40
+ end
41
+
42
+ it 'spray and scrape example' do
43
+ data = {
44
+ :first => 'Inzynier',
45
+ :last => 'Maliniak',
46
+ :gender => 'M',
47
+ :dob => '03/25/1956',
48
+ :street => '1313 Lucky Ave'
49
+ }
50
+ @page.spray data # send params to the page to enter the data
51
+ data_return = @page.scrape data.keys
52
+ data_return.should == data
53
+ end
54
+ end
55
+
File without changes
@@ -0,0 +1,263 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <title>RSpec results</title>
8
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9
+ <meta http-equiv="Expires" content="-1" />
10
+ <meta http-equiv="Pragma" content="no-cache" />
11
+ <style type="text/css">
12
+ body {
13
+ margin: 0;
14
+ padding: 0;
15
+ background: #fff;
16
+ font-size: 80%;
17
+ }
18
+ </style>
19
+ <script type="text/javascript">
20
+ // <![CDATA[
21
+ function moveProgressBar(percentDone) {
22
+ document.getElementById("rspec-header").style.width = percentDone +"%";
23
+ }
24
+ function makeRed(element_id) {
25
+ document.getElementById(element_id).style.background = '#C40D0D';
26
+ document.getElementById(element_id).style.color = '#FFFFFF';
27
+ }
28
+
29
+ function makeYellow(element_id) {
30
+ if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
31
+ {
32
+ document.getElementById(element_id).style.background = '#FAF834';
33
+ document.getElementById(element_id).style.color = '#000000';
34
+ }
35
+ else
36
+ {
37
+ document.getElementById(element_id).style.background = '#FAF834';
38
+ document.getElementById(element_id).style.color = '#000000';
39
+ }
40
+ }
41
+
42
+ // ]]>
43
+ </script>
44
+ <style type="text/css">
45
+ #rspec-header {
46
+ background: #65C400; color: #fff; height: 4em;
47
+ }
48
+
49
+ .rspec-report h1 {
50
+ margin: 0px 10px 0px 10px;
51
+ padding: 10px;
52
+ font-family: "Lucida Grande", Helvetica, sans-serif;
53
+ font-size: 1.8em;
54
+ position: absolute;
55
+ }
56
+
57
+ #summary {
58
+ margin: 0; padding: 5px 10px;
59
+ font-family: "Lucida Grande", Helvetica, sans-serif;
60
+ text-align: right;
61
+ top: 0px;
62
+ right: 0px;
63
+ float:right;
64
+ }
65
+
66
+ #summary p {
67
+ margin: 0 0 0 2px;
68
+ }
69
+
70
+ #summary #totals {
71
+ font-size: 1.2em;
72
+ }
73
+
74
+ .example_group {
75
+ margin: 0 10px 5px;
76
+ background: #fff;
77
+ }
78
+
79
+ dl {
80
+ margin: 0; padding: 0 0 5px;
81
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
82
+ }
83
+
84
+ dt {
85
+ padding: 3px;
86
+ background: #65C400;
87
+ color: #fff;
88
+ font-weight: bold;
89
+ }
90
+
91
+ dd {
92
+ margin: 5px 0 5px 5px;
93
+ padding: 3px 3px 3px 18px;
94
+ }
95
+
96
+ dd.spec.passed {
97
+ border-left: 5px solid #65C400;
98
+ border-bottom: 1px solid #65C400;
99
+ background: #DBFFB4; color: #3D7700;
100
+ }
101
+
102
+ dd.spec.failed {
103
+ border-left: 5px solid #C20000;
104
+ border-bottom: 1px solid #C20000;
105
+ color: #C20000; background: #FFFBD3;
106
+ }
107
+
108
+ dd.spec.not_implemented {
109
+ border-left: 5px solid #FAF834;
110
+ border-bottom: 1px solid #FAF834;
111
+ background: #FCFB98; color: #131313;
112
+ }
113
+
114
+ dd.spec.pending_fixed {
115
+ border-left: 5px solid #0000C2;
116
+ border-bottom: 1px solid #0000C2;
117
+ color: #0000C2; background: #D3FBFF;
118
+ }
119
+
120
+ .backtrace {
121
+ color: #000;
122
+ font-size: 12px;
123
+ }
124
+
125
+ a {
126
+ color: #BE5C00;
127
+ }
128
+
129
+ /* Ruby code, style similar to vibrant ink */
130
+ .ruby {
131
+ font-size: 12px;
132
+ font-family: monospace;
133
+ color: white;
134
+ background-color: black;
135
+ padding: 0.1em 0 0.2em 0;
136
+ }
137
+
138
+ .ruby .keyword { color: #FF6600; }
139
+ .ruby .constant { color: #339999; }
140
+ .ruby .attribute { color: white; }
141
+ .ruby .global { color: white; }
142
+ .ruby .module { color: white; }
143
+ .ruby .class { color: white; }
144
+ .ruby .string { color: #66FF00; }
145
+ .ruby .ident { color: white; }
146
+ .ruby .method { color: #FFCC00; }
147
+ .ruby .number { color: white; }
148
+ .ruby .char { color: white; }
149
+ .ruby .comment { color: #9933CC; }
150
+ .ruby .symbol { color: white; }
151
+ .ruby .regex { color: #44B4CC; }
152
+ .ruby .punct { color: white; }
153
+ .ruby .escape { color: white; }
154
+ .ruby .interp { color: white; }
155
+ .ruby .expr { color: white; }
156
+
157
+ .ruby .offending { background-color: gray; }
158
+ .ruby .linenum {
159
+ width: 75px;
160
+ padding: 0.1em 1em 0.2em 0;
161
+ color: #000000;
162
+ background-color: #FFFBD3;
163
+ }
164
+
165
+ </style>
166
+ </head>
167
+ <body>
168
+ <div class="rspec-report">
169
+
170
+ <div id="rspec-header">
171
+ <div id="label">
172
+ <h1>RSpec Code Examples</h1>
173
+ </div>
174
+
175
+ <div id="summary">
176
+ <p id="totals">&nbsp;</p>
177
+ <p id="duration">&nbsp;</p>
178
+ </div>
179
+ </div>
180
+
181
+ <div class="results">
182
+ <div class="example_group">
183
+ <dl>
184
+ <dt id="example_group_1">text field wrapped in label tag without for attribute defined</dt>
185
+ <script type="text/javascript">makeRed('rspec-header');</script>
186
+ <script type="text/javascript">makeRed('example_group_1');</script>
187
+ <script type="text/javascript">moveProgressBar('0.9');</script>
188
+ <dd class="spec failed">
189
+ <span class="failed_spec_name">parent of text_field should be Watir Element</span>
190
+ <div class="failure" id="failure_1">
191
+ <div class="message"><pre>undefined method `kind_of??' for &quot;&quot;:String</pre></div>
192
+ <div class="backtrace"><pre>./spec/label_spec.rb:17:</pre></div>
193
+ <pre class="ruby"><code><span class="linenum">15</span> <span class="keyword">if</span> <span class="ident">browser</span><span class="punct">.</span><span class="ident">kind_of?</span><span class="punct">(</span><span class="constant">FireWatir</span><span class="punct">::</span><span class="constant">Firefox</span><span class="punct">)</span>
194
+ <span class="linenum">16</span> <span class="ident">first</span><span class="punct">.</span><span class="ident">parent</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">be_kind_of</span><span class="punct">(</span><span class="constant">String</span><span class="punct">)</span>
195
+ <span class="offending"><span class="linenum">17</span> <span class="ident">last</span><span class="punct">.</span><span class="ident">parent</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">be_kind_of?</span><span class="punct">(</span><span class="constant">String</span><span class="punct">)</span></span>
196
+ <span class="linenum">18</span> <span class="ident">flunk</span><span class="punct">('</span><span class="string">FIXME Firefox returns String for parent and not Element</span><span class="punct">')</span>
197
+ <span class="linenum">19</span> </code></pre>
198
+ </div>
199
+ </dd>
200
+ <script type="text/javascript">moveProgressBar('1.8');</script>
201
+ <dd class="spec failed">
202
+ <span class="failed_spec_name">parent tagName should be a LABEL</span>
203
+ <div class="failure" id="failure_2">
204
+ <div class="message"><pre>undefined method `flunk' for #&lt;Spec::Example::ExampleGroup::Subclass_1:0x33ca070&gt;</pre></div>
205
+ <div class="backtrace"><pre>./spec/label_spec.rb:33:</pre></div>
206
+ <pre class="ruby"><code><span class="linenum">31</span>
207
+ <span class="linenum">32</span> <span class="keyword">elsif</span> <span class="ident">browser</span><span class="punct">.</span><span class="ident">kind_of?</span><span class="punct">(</span><span class="constant">FireWatir</span><span class="punct">::</span><span class="constant">Firefox</span><span class="punct">)</span>
208
+ <span class="offending"><span class="linenum">33</span> <span class="ident">flunk</span><span class="punct">('</span><span class="string">FIXME Firefox returns String for parent and not Element</span><span class="punct">')</span></span>
209
+ <span class="linenum">34</span> <span class="keyword">end</span>
210
+ <span class="linenum">35</span> <span class="keyword">end</span></code></pre>
211
+ </div>
212
+ </dd>
213
+ <script type="text/javascript">moveProgressBar('2.7');</script>
214
+ <dd class="spec failed">
215
+ <span class="failed_spec_name">parent text returns text of label</span>
216
+ <div class="failure" id="failure_3">
217
+ <div class="message"><pre>undefined method `flunk' for #&lt;Spec::Example::ExampleGroup::Subclass_1:0x3324cd8&gt;</pre></div>
218
+ <div class="backtrace"><pre>./spec/label_spec.rb:43:</pre></div>
219
+ <pre class="ruby"><code><span class="linenum">41</span>
220
+ <span class="linenum">42</span> <span class="keyword">elsif</span> <span class="ident">browser</span><span class="punct">.</span><span class="ident">kind_of?</span><span class="punct">(</span><span class="constant">FireWatir</span><span class="punct">::</span><span class="constant">Firefox</span><span class="punct">)</span>
221
+ <span class="offending"><span class="linenum">43</span> <span class="ident">flunk</span><span class="punct">('</span><span class="string">FIXME Firefox returns String for parent and not Element.</span><span class="punct">')</span></span>
222
+ <span class="linenum">44</span> <span class="keyword">end</span>
223
+ <span class="linenum">45</span> <span class="keyword">end</span></code></pre>
224
+ </div>
225
+ </dd>
226
+ </dl>
227
+ </div>
228
+ <div class="example_group">
229
+ <dl>
230
+ <dt id="example_group_2">label for text field not wrapped</dt>
231
+ <script type="text/javascript">moveProgressBar('3.6');</script>
232
+ <dd class="spec passed"><span class="passed_spec_name">text value of label</span></dd>
233
+ </dl>
234
+ </div>
235
+ <div class="example_group">
236
+ <dl>
237
+ <dt id="example_group_3">SelectList selections</dt>
238
+ <script type="text/javascript">moveProgressBar('4.5');</script>
239
+ <dd class="spec passed"><span class="passed_spec_name">selected returns preselected item in single select</span></dd>
240
+ <script type="text/javascript">moveProgressBar('5.4');</script>
241
+ <dd class="spec passed"><span class="passed_spec_name">selected returns preselected value in single select</span></dd>
242
+ <script type="text/javascript">moveProgressBar('6.3');</script>
243
+ <dd class="spec passed"><span class="passed_spec_name">selected returns nil for none selected items in multi select</span></dd>
244
+ <script type="text/javascript">moveProgressBar('7.2');</script>
245
+ <dd class="spec passed"><span class="passed_spec_name">selected returns nil for none selected values in multi select</span></dd>
246
+ <script type="text/javascript">moveProgressBar('8.1');</script>
247
+ <dd class="spec passed"><span class="passed_spec_name">set item text and find selected item and text for multiselect</span></dd>
248
+ <script type="text/javascript">moveProgressBar('9.0');</script>
249
+ <dd class="spec passed"><span class="passed_spec_name">set value and find selected item and value for multiselect</span></dd>
250
+ <script type="text/javascript">moveProgressBar('10.0');</script>
251
+ <dd class="spec passed"><span class="passed_spec_name">set and query option by text for single select</span></dd>
252
+ <script type="text/javascript">moveProgressBar('10.9');</script>
253
+ <dd class="spec passed"><span class="passed_spec_name">set and query option by value for single select</span></dd>
254
+ <script type="text/javascript">moveProgressBar('11.8');</script>
255
+ <dd class="spec passed"><span class="passed_spec_name">set by text multple items for multiselect selects each item</span></dd>
256
+ <script type="text/javascript">moveProgressBar('12.7');</script>
257
+ <dd class="spec passed"><span class="passed_spec_name">set by value multple items for multiselect selects each item</span></dd>
258
+ <script type="text/javascript">moveProgressBar('13.6');</script>
259
+ <dd class="spec passed"><span class="passed_spec_name">set items array for single select selects each in turn. selected is the last item in array</span></dd>
260
+ <script type="text/javascript">moveProgressBar('14.5');</script>
261
+ <dd class="spec passed"><span class="passed_spec_name">set item after multiple items were set returns all values selected for multiselect</span></dd>
262
+ <script type="text/javascript">moveProgressBar('15.4');</script>
263
+ <dd class="spec passed"><span class="passed_spec_name">set using position for multiselect</span></dd>