watirloo 0.0.7

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 (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