watirloo 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.gitignore +22 -0
  2. data/History.txt +44 -0
  3. data/Manifest.txt +59 -0
  4. data/README.rdoc +94 -0
  5. data/Rakefile +68 -0
  6. data/VERSION +1 -0
  7. data/lib/watirloo/browsers.rb +73 -0
  8. data/lib/watirloo/desktop.rb +44 -0
  9. data/lib/watirloo/extension/firewatir_ducktape.rb +194 -0
  10. data/lib/watirloo/extension/object.rb +32 -0
  11. data/lib/watirloo/extension/watir_ducktape.rb +552 -0
  12. data/lib/watirloo/extension/watir_reflector.rb +83 -0
  13. data/lib/watirloo/locker.rb +85 -0
  14. data/lib/watirloo/page.rb +140 -0
  15. data/lib/watirloo.rb +16 -0
  16. data/spec/browser_spec.rb +38 -0
  17. data/spec/browser_threads_spec.rb +45 -0
  18. data/spec/checkbox_group_spec.rb +136 -0
  19. data/spec/checkbox_groups_spec.rb +55 -0
  20. data/spec/checkboxes_value_spec.rb +35 -0
  21. data/spec/desktop_spec.rb +54 -0
  22. data/spec/extra/browser_events_spec.rb +76 -0
  23. data/spec/extra/page_objects_metrics.rb +139 -0
  24. data/spec/face_mixing_spec.rb +55 -0
  25. data/spec/firewatir/attach_instance_test.rb +38 -0
  26. data/spec/firewatir/spec_results.html +263 -0
  27. data/spec/firewatir/spec_results.txt +23 -0
  28. data/spec/firewatir/spec_results_failed.txt +3 -0
  29. data/spec/html/census.html +332 -0
  30. data/spec/html/checkbox_group1.html +33 -0
  31. data/spec/html/frameset1.html +17 -0
  32. data/spec/html/labels.html +53 -0
  33. data/spec/html/no_title.html +13 -0
  34. data/spec/html/person.html +37 -0
  35. data/spec/html/radio_group.html +35 -0
  36. data/spec/html/select_lists.html +82 -0
  37. data/spec/input_element_spec.rb +51 -0
  38. data/spec/label_spec.rb +65 -0
  39. data/spec/locker_spec.rb +49 -0
  40. data/spec/page_spec.rb +91 -0
  41. data/spec/person_def_wrappers_spec.rb +40 -0
  42. data/spec/radio_group_spec.rb +95 -0
  43. data/spec/radio_groups_spec.rb +55 -0
  44. data/spec/reflector_spec.rb +82 -0
  45. data/spec/select_list_options_spec.rb +40 -0
  46. data/spec/select_lists_spec.rb +151 -0
  47. data/spec/spec_helper.rb +20 -0
  48. data/spec/spec_helper_ff.rb +5 -0
  49. data/spec/spec_helper_runner.rb +13 -0
  50. data/spec/spec_results.html +556 -0
  51. data/spec/spec_results.txt +175 -0
  52. data/spec/spec_results_failed.txt +1 -0
  53. data/spec/text_fields_spec.rb +56 -0
  54. data/watirloo.gemspec +122 -0
  55. metadata +150 -0
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ spec/reports
20
+ pkg
21
+
22
+ ## PROJECT::SPECIFIC
data/History.txt ADDED
@@ -0,0 +1,44 @@
1
+ == 0.0.6 22Jul2009
2
+ * make page container the receiver of all face methods implicitly
3
+ * some cleanup
4
+ * 117 examples in rspec
5
+ * locker moved to temp. remove log/locker.yml mechanism
6
+
7
+ == 0.0.5 22Jul2009
8
+ * Page is a module and not a class. include Watirloo::Page in your testcase (rspec group or cucumber feature) to add view methods.
9
+ * Locker uses log/locker.yml by default. If you want your own somewhere in your project update the Watirloo::Locker.locker = "path/to/your/log/locker.yml"
10
+ * multiple browser support with Watirloo::Desktop and Locker
11
+ * 115 examples in rspec
12
+
13
+ == 0.0.4 16feb2009
14
+ * Radio and Checkbox Groups, UseCase class and reflector
15
+ * RadioGroups class and enhance radio_group(how, what) method
16
+ * CheckboxGroups class and enhance checkbox_group(how, what) method
17
+ * ElementCollections.reflect and Container.reflect method redesign
18
+
19
+ == 0.0.3 25jan2009
20
+
21
+ * implement inheritable class interfaces
22
+ * subclasses inherit class level interfaces from superclasses
23
+ * initialize makes a set of interfaces to that instance only but inherits class interfaces from entire tree
24
+ * adding interfaces to the instance does not leak into classes
25
+
26
+ == 0.0.2 03jan2009
27
+
28
+ * implement radio_group and checkbox_group for IE and Firefox
29
+ * Create RadioGroup and CheckboxGroup class for Watir::IE and FireWatir::Firefox
30
+ * update tests to run for both browsers unchanged.
31
+
32
+ == 0.0.1 22dec2008
33
+
34
+ * initial merge with newgem generated structure to make it a gem
35
+ * Patches to Watir and Firewatir
36
+ * radio_group method added to Watir (not to FireWatir yet)
37
+ * patch fof Firefox.attach to just attach to the latest window without starting new ff win.
38
+ * tests
39
+ * built with intent to run unchanged on IE and Firefox
40
+ * tests run on test/spec gem
41
+
42
+ == 0.0.0
43
+
44
+ * start collecting ideas about building an abstratction layer based on semantic domain model vocabulary customers speak.
data/Manifest.txt ADDED
@@ -0,0 +1,59 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile.rb
5
+ lib/watirloo.rb
6
+ lib/watirloo/browsers.rb
7
+ lib/watirloo/desktop.rb
8
+ lib/watirloo/extension/firewatir_ducktape.rb
9
+ lib/watirloo/extension/object.rb
10
+ lib/watirloo/extension/watir_ducktape.rb
11
+ lib/watirloo/extension/watir_reflector.rb
12
+ lib/watirloo/locker.rb
13
+ lib/watirloo/page.rb
14
+ script/console
15
+ script/console.cmd
16
+ script/destroy
17
+ script/destroy.cmd
18
+ script/generate
19
+ script/generate.cmd
20
+ script/reflect.rb
21
+ spec/browser_spec.rb
22
+ spec/browser_threads_spec.rb
23
+ spec/checkbox_group_spec.rb
24
+ spec/checkbox_groups_spec.rb
25
+ spec/checkboxes_value_spec.rb
26
+ spec/desktop_spec.rb
27
+ spec/extra/browser_events_spec.rb
28
+ spec/extra/page_objects_metrics.rb
29
+ spec/face_mixing_spec.rb
30
+ spec/firewatir/attach_instance_test.rb
31
+ spec/firewatir/spec_results.html
32
+ spec/firewatir/spec_results.txt
33
+ spec/firewatir/spec_results_failed.txt
34
+ spec/html/census.html
35
+ spec/html/checkbox_group1.html
36
+ spec/html/frameset1.html
37
+ spec/html/labels.html
38
+ spec/html/no_title.html
39
+ spec/html/person.html
40
+ spec/html/radio_group.html
41
+ spec/html/select_lists.html
42
+ spec/input_element_spec.rb
43
+ spec/label_spec.rb
44
+ spec/locker_spec.rb
45
+ spec/page_spec.rb
46
+ spec/person_def_wrappers_spec.rb
47
+ spec/radio_group_spec.rb
48
+ spec/radio_groups_spec.rb
49
+ spec/reflector_spec.rb
50
+ spec/select_list_options_spec.rb
51
+ spec/select_lists_spec.rb
52
+ spec/spec_helper.rb
53
+ spec/spec_helper_ff.rb
54
+ spec/spec_helper_runner.rb
55
+ spec/spec_results.html
56
+ spec/spec_results.txt
57
+ spec/spec_results_failed.txt
58
+ spec/text_fields_spec.rb
59
+ watirloo.gemspec
data/README.rdoc ADDED
@@ -0,0 +1,94 @@
1
+ = Watirloo
2
+
3
+ * http://github.com/marekj/watirloo
4
+
5
+ == DESCRIPTION:
6
+
7
+ Custom Extensions for Watir, Firewatir. Acceptance Test Helper based on semantic page objects modeling customer's domain language
8
+ It helps you write human readable and machine executable browser tests. Isolates GUI from Tests.
9
+
10
+ The Human Readable part helps you create interfaces to elements on the page and tags them with friendly names
11
+ based on vocabulary of Business Domain. The Machine Executable parts talk to Watir API hooking into DOM elements.
12
+ it helps you concentrate in your acceptance tests on the intention and the customer's language and not on implementation of DOM.
13
+ Write customer facing tests hence the metaphor of face for Page Objects of Significance to the Customer.
14
+
15
+ == FEATURES/PROBLEMS:
16
+
17
+ * Extensions to Watir and Firewatir gems to ease testing and joy with page objects
18
+ * group radios in #radio_group and checkboxes in #checkbox_group and acts each group as page object
19
+ * Maintains multiple browsers on the desktop and stores window handles so you can reattach to the browser under test later (see Watirloo::Locker)
20
+ * Watches and maintains your desktop for browsers existence. (Watirloo::Desktop)
21
+ * Browser is managed automatically with Watirloo::browser
22
+ * Isolates GUI from tests with face methods that introduce customer facing friendly names for elements
23
+ * add reflect method to generate scaffolding code for your page elements (reflect currently uses browser as container. Alter scaffodling if you use frames)
24
+ * look at spec dir for examples of usage with rspec
25
+
26
+
27
+ == SYNOPSIS:
28
+
29
+ By convention Watirloo::browser attaches itself to the existing IE browser instance on the desktop and maintains the handles to reattach later
30
+
31
+ Example:
32
+
33
+ Given a page with text fields for last name and first name
34
+ When I want to enter the name 'Kurt Vonnegut'
35
+ And I don't want to talk to implementation
36
+ But I want a friendly name of element on the page
37
+ Then I use Watirloo shortcuts
38
+ When I define an interface to watir implementation with a semantic key
39
+ And I define my data as hash with the same semantic key
40
+ Then I can automatically let watirloo enter my test data on a page
41
+
42
+ # rspec as client
43
+
44
+ describe "using watirloo page to isolate and bind gui view to data" do
45
+ include Watirloo::Page
46
+ face(:last_name) { text_field(:name, 'l_nm') }
47
+ face(:first_name) { text_field(:name, 'f_nm') }
48
+
49
+ it "enters data on the page" do
50
+ first_name.set "Kurt"
51
+ last_name.set "Vonnegut"
52
+ end
53
+
54
+ it "sprays data on elements defined" do
55
+ spray :last_name => 'Vonnegut', :first_name => 'Kurt'
56
+ end
57
+
58
+ it "grabs data from elements and validates" do
59
+ data = {:first_name => "Kurt", :last_name => 'Vonnegut'}
60
+ spray data
61
+ scrape(data.keys).should == data
62
+ end
63
+
64
+ end
65
+
66
+ == REQUIREMENTS:
67
+
68
+ * watir = 1.6.2
69
+ * firewatir = 1.6.2 if you want to use Firefox
70
+ * rspec gem if you want to run watirloo examples included
71
+
72
+ == INSTALL:
73
+
74
+ * Run the following if you haven't already:
75
+ gem sources -a http://gems.github.com
76
+
77
+ * Install the gem(s):
78
+ gem install marekj-watirloo
79
+
80
+ * or download from : http://github.com/marekj/watirloo/downloads
81
+
82
+ === ROADMAP
83
+
84
+ * add Logging gem and log all actions for audit
85
+ * provide UserStory type of container for exploratory testing (UseCase, Feature, TestScenario etc...)
86
+ * provide examples for Cucumber
87
+ * make specs run with firewatir
88
+
89
+ == LICENSE
90
+
91
+ (The MIT License)
92
+
93
+ Copyright (c) 2008 marekj
94
+ http://www.opensource.org/licenses/mit-license.php
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "watirloo"
8
+ gem.summary = %Q{small Watir framework based on semantic page object adapters for DOM elements}
9
+ gem.description = %Q{Helps you write tests in the language of the customer's domain}
10
+ gem.email = "marekj.com@gmail.com"
11
+ gem.homepage = "http://github.com/marekj/watirloo"
12
+ gem.authors = ["marekj"]
13
+ gem.add_dependency 'watir', '>=1.6.2'
14
+ gem.add_development_dependency 'rspec', '>= 1.2.7'
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+
23
+ require 'spec/rake/spectask'
24
+ desc "spec with ie browser"
25
+ Spec::Rake::SpecTask.new do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.spec_files = FileList['spec/*_spec.rb']
28
+ spec.spec_files.exclude('spec/reflector*') #TODO fix reflector feature
29
+ spec.fail_on_error = false
30
+ spec.spec_opts = [
31
+ "--color",
32
+ "--require spec/spec_helper_runner.rb", # slow execution expected. closes all browsers on desktop before :all
33
+ "--format specdoc",
34
+ "--format specdoc:spec/spec_results.txt",
35
+ "--format failing_examples:spec/spec_results_failed.txt",
36
+ "--format html:spec/spec_results.html",
37
+ #"--diff",
38
+ "--loadby mtime",
39
+ #"--dry-run", # will overwrite any previous spec_results
40
+ #"--generate-options spec/spec.opts",
41
+ ]
42
+ end
43
+
44
+ # FIXME fix the spec FileList to only include those that execut for firefox. use taglog lib
45
+ desc "spec with ff browser"
46
+ Spec::Rake::SpecTask.new(:spec_ff) do |t|
47
+ t.spec_files = FileList['spec/*_spec.rb']
48
+ t.spec_opts = [
49
+ "--color",
50
+ "--require spec/spec_helper_ff.rb",
51
+ "--format specdoc",
52
+ "--format specdoc:spec/firewatir/spec_results.txt",
53
+ "--format failing_examples:spec/firewatir/spec_results_failed.txt",
54
+ "--format html:spec/firewatir/spec_results.html",
55
+ "--loadby mtime" ]
56
+ end
57
+
58
+ #task :default => :spec
59
+
60
+ require 'rake/rdoctask'
61
+ Rake::RDocTask.new do |rdoc|
62
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
63
+
64
+ rdoc.rdoc_dir = 'rdoc'
65
+ rdoc.title = "watirloo #{version}"
66
+ rdoc.rdoc_files.include('README*')
67
+ rdoc.rdoc_files.include('lib/**/*.rb')
68
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.7
@@ -0,0 +1,73 @@
1
+ module Watirloo
2
+
3
+ # This is 'opinionated' method.
4
+ # The way I work with browsers is this:
5
+ # I save the current handle of the browser (ie.hwnd) to the storage yaml file so I can reattach to the same
6
+ # browser later. Basically in exploratory testing I don't want to start and close browsers. I want to maintain
7
+ # reference to one (or more) browsers and I have nicknames for them.
8
+ # on restart of tests useing Watirloo I reuse the browser. If the browser is not there I just start a new browser which
9
+ # will from now on become my new 'default' test session browser.
10
+ # In Case of Firefox I attach to the 'one' existing firefox or a start a new one.
11
+ # So this method either attaches to one that's there or it starts a new one and puts it in Browsers::Storage
12
+ # this way of working with browsers is opinionated I think.
13
+ # if you want you can just use Watir::IE.start and reuse that browsers for tests. This here is a convenience method
14
+ def self.browser(key = 'default')
15
+ case Browsers.target
16
+ when :ie then Browsers.ie key
17
+ when :firefox then Browsers.ff
18
+ end
19
+ end
20
+
21
+ # manage references to browsers. Currently IE or Firefox.
22
+ # Safari? Other Browser? not yet
23
+ module Browsers
24
+
25
+ @@target = :ie #by default we talk to IE on Windows.
26
+ @@targets = [:ie, :firefox]
27
+
28
+ class << self
29
+
30
+ # set and get the target. by default we talk to :ie.
31
+ def target
32
+ return @@target
33
+ end
34
+
35
+ def target=(indicator)
36
+ if @@targets.include? indicator
37
+ @@target = indicator
38
+ else
39
+ raise Exception, "target indicator #{indicator} is not valid: use :ie or :firefox"
40
+ end
41
+ end
42
+
43
+
44
+ # provides browser instance to client.
45
+ # attaches to the existing 'default' test session browser on the desktop
46
+ # By convention the mental model here is that we are working
47
+ # with one browser on the desktop. This is how a person would typically work
48
+ def ie(key='default')
49
+ begin
50
+ Locker.browser key
51
+ rescue #XXX it's probably a bad practice to use exception for logic control
52
+ # TODO logger here
53
+ ie = Watir::IE.start
54
+ sleep 3
55
+ Locker.add(ie, key)
56
+ ie #return newly created browser for the test session and store it for laterusage
57
+ end
58
+ end
59
+
60
+ def ff
61
+ require 'watirloo/firewatir_ducktape'
62
+ # this is a cruch for quick work with pages.
63
+ # in reality you want to create a browser and pass it as argument to initialize Page class
64
+ begin
65
+ FireWatir::Firefox.attach #this attach is a crutch
66
+ rescue
67
+ puts 'got to start browser ff dude'
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,44 @@
1
+ module Watirloo
2
+
3
+ # The browser desktop manager
4
+ # checks to see what browsers already exist on the dekstop.
5
+ # compares what is on the desktop to what was there last time
6
+ module Desktop
7
+
8
+ class << self
9
+
10
+ # returns browser windows found on the desktop
11
+ def browsers
12
+ brs =[]
13
+ Watir::IE.each {|ie| brs << ie }
14
+ brs
15
+ end
16
+
17
+ # return handles of Browsers found on desktop
18
+ def hwnds
19
+ hs =[]
20
+ browsers.each {|ie| hs << ie.hwnd}
21
+ hs
22
+ end
23
+
24
+ # returns handles for browsers that appeared on Desktop since the last scan for browsers
25
+ def additions(known_hwnds)
26
+ hwnds.select {|h| !known_hwnds.include?(h)}
27
+ end
28
+
29
+ # returns handles for browsers no longer found on the Desktop since the last scan for browsers
30
+ def deletions(known_hwnds)
31
+ known_hwnds.select {|h| !hwnds.include?(h)}
32
+ end
33
+
34
+ # Closes all the browsers on the desktop.
35
+ # Creats a known clear slate where no browsers exist
36
+ def clear
37
+ browsers.each {|ie| ie.close; sleep 3}
38
+ sleep 3
39
+ raise Exception, "Failed to clear all the browsers from the desktop" unless browsers.empty?
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,194 @@
1
+ gem 'firewatir', '>=1.6.2' # dependency
2
+ require 'firewatir'
3
+
4
+ module FireWatir
5
+
6
+ # duck punch and ducktape Firefox for Watirloo needs
7
+ # some of it is cosmetic surgery and some new methods with intention of
8
+ # sending a patch to Watir maintainers
9
+ class Firefox
10
+
11
+ # attach to the existing Firefox that was already started with JSSH option.
12
+ # this is a hack for Watirloo. it only attaches to the latest firefox.
13
+ # it assumes there is only one instance of FF window open on the desktop
14
+ def self.attach
15
+ Firefox.new :attach => true
16
+ end
17
+
18
+ # add option key :attach as a hack
19
+ # :attach => true to attach to topmost window in getWindows().lenght-1
20
+ # split up initialize to conditionally start FireFox
21
+ def initialize(options = {})
22
+ _start_firefox(options) unless options[:attach]
23
+ set_defaults()
24
+ get_window_number()
25
+ set_browser_document()
26
+ end
27
+
28
+ # refactor initialize method to move all starting of FF into its own method
29
+ def _start_firefox(options)
30
+ if(options.kind_of?(Integer))
31
+ options = {:waitTime => options}
32
+ end
33
+
34
+ if(options[:profile])
35
+ profile_opt = "-no-remote -P #{options[:profile]}"
36
+ else
37
+ profile_opt = ""
38
+ end
39
+
40
+ waitTime = options[:waitTime] || 2
41
+
42
+ case RUBY_PLATFORM
43
+ when /mswin/
44
+ # Get the path to Firefox.exe using Registry.
45
+ require 'win32/registry.rb'
46
+ path_to_bin = ""
47
+ Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Mozilla\Mozilla Firefox') do |reg|
48
+ keys = reg.keys
49
+ reg1 = Win32::Registry::HKEY_LOCAL_MACHINE.open("SOFTWARE\\Mozilla\\Mozilla Firefox\\#{keys[0]}\\Main")
50
+ reg1.each do |subkey, type, data|
51
+ if(subkey =~ /pathtoexe/i)
52
+ path_to_bin = data
53
+ end
54
+ end
55
+ end
56
+
57
+ when /linux/i
58
+ path_to_bin = `which firefox`.strip
59
+ when /darwin/i
60
+ path_to_bin = '/Applications/Firefox.app/Contents/MacOS/firefox'
61
+ when /java/
62
+ raise "Not implemented: Create a browser finder in JRuby"
63
+ end
64
+
65
+ @t = Thread.new { system("#{path_to_bin} -jssh #{profile_opt}")}
66
+ sleep waitTime
67
+
68
+ end
69
+ private :_start_firefox
70
+
71
+ end
72
+
73
+ class SelectList
74
+
75
+ include Watir::SelectListCommonWatir
76
+
77
+ # accepts one text item or array of text items. if array then sets one after another.
78
+ # For single select lists the last item in array wins
79
+ #
80
+ # examples
81
+ # select_list.set 'bla' # => single option text
82
+ # select_list.set ['bla','foo','gugu'] # => set 3 options by text. If
83
+ # this is a single select list box it will set each value in turn
84
+ # select_list set 1 # => set the first option in a list
85
+ # select_list.set [1,3,5] => set the first, third and fith options
86
+ def set(item)
87
+ _set(:text, item)
88
+ end
89
+
90
+ # set item by the option value attribute. if array then set one after anohter.
91
+ # see examples in set method
92
+ def set_value(value)
93
+ _set(:value, value)
94
+ end
95
+
96
+ # returns array of value attributes
97
+ # each option usually has a value attribute
98
+ # which is hidden to the person viewing the page
99
+ def values
100
+ a = []
101
+ items.each do |item|
102
+ a << option(:text, item).value
103
+ end
104
+ return a
105
+ end
106
+
107
+ alias clear clearSelection
108
+
109
+ # alias, items or contents return the same visible text items
110
+ alias items getAllContents
111
+
112
+ end
113
+
114
+ # RadioGroup and CheckboxGroup common behaviour
115
+ module RadioCheckGroup
116
+
117
+ include Watir::RadioCheckGroupCommonWatir
118
+
119
+ def values
120
+ values = []
121
+ @o.each {|thing| values << thing.value}
122
+ return values
123
+ end
124
+
125
+ def get_by_value value
126
+ if values.member? value
127
+ @o.find {|thing| thing.value == value}
128
+ else
129
+ raise ::Watir::Exception::WatirException, "value #{value} not found in hidden values"
130
+ end
131
+ end
132
+ end
133
+
134
+ class CheckboxGroup
135
+
136
+ include RadioCheckGroup
137
+ include Watir::CheckboxGroupCommonWatir
138
+
139
+ def initialize(container, name)
140
+ @container = container
141
+ @name = name
142
+ @o = []
143
+ @container.checkboxes.each do |cb| #TODO find why find_all does not work
144
+ if cb.name == @name
145
+ @o << cb
146
+ end
147
+ end
148
+ end
149
+
150
+ # which values are selected?
151
+ def selected_values
152
+ values = []
153
+ selected_checkboxes.each do |cb|
154
+ values << cb.value
155
+ end
156
+ return values
157
+ end
158
+ end
159
+
160
+ class RadioGroup
161
+
162
+ include RadioCheckGroup
163
+ include Watir::RadioGroupCommonWatir
164
+
165
+ def initialize(container, name)
166
+ @container = container
167
+ @name = name
168
+ @o = []
169
+ @container.radios.each do |r| #TODO find why find_all does not work
170
+ if r.name == @name
171
+ @o << r
172
+ end
173
+ end
174
+ return @o
175
+ end
176
+
177
+ # see Watir::RadioGroup.selected_value
178
+ def selected_value
179
+ selected_radio.value
180
+ end
181
+ alias selected selected_value
182
+ end
183
+
184
+
185
+ module Container
186
+ def radio_group(name)
187
+ RadioGroup.new(self, name)
188
+ end
189
+
190
+ def checkbox_group(name)
191
+ CheckboxGroup.new(self, name)
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,32 @@
1
+
2
+ # http://blog.jayfields.com/2006/09/ruby-instanceexec-aka-instanceeval.html # hints on usage
3
+ # http://blog.jayfields.com/2008/02/ruby-dynamically-define-method.html # write up on usage
4
+ # http://eigenclass.org/hiki.rb?instance_exec # more study
5
+ # http://eigenclass.org/hiki.rb?bounded+space+instance_exec # fix for mem leak final used here
6
+ # http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l23
7
+ # http://www.jroller.com/abstractScope/entry/passing_parameters_to_an_instance
8
+ # instance_exec is used for face methods it allows you to pass args and block to be evaled.
9
+ # it works like instance eval but instance eval does not accept arguments
10
+ if VERSION <= '1.8.6'
11
+ class Object
12
+ module InstanceExecHelper; end
13
+ include InstanceExecHelper
14
+ # instance_exec method evaluates a block of code relative to the specified object, with parameters whom come from outside the object.
15
+ def instance_exec(*args, &block)
16
+ begin
17
+ old_critical, Thread.critical = Thread.critical, true
18
+ n = 0
19
+ n += 1 while respond_to?(mname="__instance_exec#{n}")
20
+ InstanceExecHelper.module_eval{ define_method(mname, &block) }
21
+ ensure
22
+ Thread.critical = old_critical
23
+ end
24
+ begin
25
+ ret = send(mname, *args)
26
+ ensure
27
+ InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil
28
+ end
29
+ ret
30
+ end
31
+ end
32
+ end