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,84 @@
1
+ module Watirloo
2
+
3
+
4
+ # manages references to browsers we care about to run tests agains.
5
+ # Saves references to window handles internall to yaml file so we can reuse the browser for tests by reattaching to it between tests.
6
+ # you put reference to a browser in storage. Next time you run a test you can restore the browser's reference instead fo staring a new one.
7
+ module Locker
8
+
9
+ @@locker_file = File.join(File.dirname(__FILE__), "..", "..", "config", "locker.yml")
10
+
11
+ class << self
12
+
13
+ # hash of {key => IE.hwnd} to attach and reuse browsers
14
+ # example: mapping = {:default=> 234567, :bla => 234234}
15
+ def mapping
16
+ @mapping ||= read_mapping
17
+ end
18
+
19
+ def locker
20
+ @@locker_file
21
+ end
22
+
23
+ def locker=( locker )
24
+ @@locker_file = locker
25
+ end
26
+
27
+ # returns IE reference to a browser with a given key
28
+ def browser(key='default')
29
+ if key == 'default'
30
+ (@browser && @browser.exists?) ? @browser : @browser = attach_browser
31
+ else
32
+ attach_browser(key)
33
+ end
34
+ end
35
+
36
+ # add browser to storage for later reuse. by convention if you don't have any browsers it
37
+ # so you can later restore it and continue working with it.
38
+ # pass either browser referene or the hwnd Fixnum
39
+ def add(browser, key='default')
40
+ mapping[key] = browser.kind_of?(Watir::IE) ? browser.hwnd : browser
41
+ save_mapping
42
+ end
43
+
44
+ # remove browser from storage and from further reusing
45
+ def remove(key='default')
46
+ @browser = nil if key == 'default'
47
+ mapping.delete(key) if mapping[key]
48
+ save_mapping
49
+ end
50
+
51
+ # clear Storage
52
+ def clear
53
+ @browser = nil
54
+ mapping.clear
55
+ save_mapping
56
+ end
57
+
58
+ private
59
+
60
+ def read_mapping
61
+ if FileTest.exists?(locker)
62
+ loaded = YAML::load_file(locker)
63
+ #if file is empty or not well formed yaml
64
+ #or not a hash then return empty hash
65
+ loaded.kind_of?(Hash) ? loaded : {}
66
+ else
67
+ #empty hash if locker.yaml not there
68
+ #or malformed loaded not created yet
69
+ {}
70
+ end
71
+ end
72
+
73
+ def save_mapping
74
+ File.open(locker,'w') {|f| YAML.dump(mapping, f)}
75
+ end
76
+
77
+ # throws exception if can't attach to the known handle.
78
+ def attach_browser(key='default')
79
+ Watir::IE.attach(:hwnd, mapping[key])
80
+ end
81
+
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,105 @@
1
+ module Watirloo
2
+
3
+ # Semantic Page Objects Container
4
+ # include it in your ClientClass that manages Test. Your client class must provide an instance of browser.
5
+ # If you don't want an explicit browser the Watirloo.browser will be used.
6
+ # example
7
+ # class UsageScenarioOfSomeFeature
8
+ # include Watirloo::Page
9
+ # end
10
+ # now the client GoogleSearch can access browser and elements defined
11
+ # instead of including it directly in classes that you instantiate to keep track of state you can build modules of pages
12
+ # that you can later include into your client
13
+ module Page
14
+
15
+ # provides access to the browser for a client
16
+ def browser
17
+ ::Watirloo.browser
18
+ end
19
+
20
+ # container that delimits the scope of elements.
21
+ # in a frameless DOM the browser is the doc
22
+ # however if page with frames you can setup a doc destination to be a frame as the
23
+ # base container for face accessors
24
+ def doc
25
+ browser
26
+ end
27
+
28
+ module ClassMethods
29
+
30
+ # "anything which is the forward or world facing part of a system
31
+ # which has internal structure is considered its 'face', like the facade of a building"
32
+ # ~ http://en.wikipedia.org/wiki/Face
33
+ #
34
+ # Declares Semantic Interface to the DOM elements on the Page (facade) binds a symbol to a block of code that accesses the DOM.
35
+ # When the user speaks of filling in the last name the are usually entering data in a text_field
36
+ # we can create a semantic accessor interface like this:
37
+ # face(:last_name) {doc.text_field(:name, 'last_nm'}
38
+ # what matters to the user is on the left (:last_name) and what matters to the programmer is on the right
39
+ # The face method provides an adapter and insolates the tests form the changes in GUI.
40
+ # face(:friendlyname) { watircode } where watircode is actuall way of accessing the element on the page.
41
+ # Each interface or face is an object of interest that we want to access by its interface name
42
+ # example:
43
+ #
44
+ # class GoogleSearch
45
+ # include Watirloo::Page
46
+ # face(:query) { doc.text_field(:name, 'q') }
47
+ # face(:search) { doc.button(:name, 'btnG') }
48
+ # end
49
+ #
50
+ def face(name, *args, &definition)
51
+ module_eval do
52
+ define_method(name) do |*args|
53
+ instance_exec(*args, &definition)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ # metahook by which ClassMethods become singleton methods of an including module
60
+ # Perhaps the proper way is to do this
61
+ # class SomeClass
62
+ # include PageHelper
63
+ # extend PageHelper::ClassMethods
64
+ # end
65
+ # but we are just learning this metaprogramming
66
+ def self.included(klass)
67
+ klass.extend(ClassMethods)
68
+ end
69
+
70
+ # enter values on controls idenfied by keys on the page.
71
+ # data map is a hash, key represents the page objects that can be filled or set with values,
72
+ # value represents its value to be set, either text, array or boolean
73
+ # exmaple:
74
+ # spray :first => "Johnny", :last => 'Begood'
75
+ #
76
+ # # Given the faces defined
77
+ # face(:first) {doc.text_field(:name, 'lst_nm')}
78
+ # face(:last) {doc.text_field(:name, 'fst_nm')}
79
+ def spray(hash)
80
+ hash.each_pair do |facename, value|
81
+ send(facename).set value #make every control element in watir respond to set
82
+ end
83
+ end
84
+
85
+ # set values on the page given the interface keys
86
+ alias set spray
87
+
88
+
89
+ def scrape(field_keys)
90
+ data = {}
91
+ field_keys.each do |k|
92
+ watir_control = send("#{k}")
93
+ method_name = case watir_control.class.to_s.split("::").last
94
+ when "SelectList", "CheckboxGroup", "RadioGroup" then :selected
95
+ else
96
+ :value
97
+ end
98
+ data.update k => watir_control.send(method_name)
99
+ end
100
+ data
101
+ end
102
+
103
+
104
+ end
105
+ end
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "Watirloo browser when no browsers on desktop nor in locker" do
4
+
5
+ before(:all) do
6
+ Watirloo::Desktop.clear
7
+ Watirloo::Locker.clear
8
+ end
9
+
10
+ it "should start a default new browser and load a testfile" do
11
+ browser = Watirloo.browser
12
+ browser.should be_kind_of(Watir::IE)
13
+ browser.goto testfile('person.html')
14
+ end
15
+
16
+ it 'should attach to a default browser with loaded testfile and return its title' do
17
+ browser = Watirloo.browser
18
+ browser.should be_kind_of(Watir::IE)
19
+ browser.title.should == 'Person'
20
+ end
21
+
22
+ it "should start second browser with a named keyword" do
23
+ Watirloo.browser 'second'
24
+ end
25
+
26
+ it 'should attach to second browser with keyword and navigate to a testfile' do
27
+ browser2 = Watirloo.browser 'second'
28
+ browser2.goto testfile('census.html')
29
+ end
30
+
31
+ it 'should attach to two distinct browsers by key values by kewords used to start them' do
32
+ b2 = Watirloo.browser 'second'
33
+ b1 = Watirloo.browser 'default'
34
+ b2.title.should == 'Census'
35
+ b1.title.should == 'Person'
36
+ end
37
+
38
+ end
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'thread'
3
+
4
+ # This is more of an example of using Watirloo::browser() and Watirloo::Locker with threads
5
+ # for multibrowser testing possiblilities
6
+ describe "Watirloo multiple browsers and threads" do
7
+
8
+ before(:all) do
9
+ Watirloo::Desktop.clear
10
+ Watirloo::Locker.clear
11
+ end
12
+
13
+
14
+ it "open 5 new browsers in threads and add them to locker" do
15
+ threads = []
16
+ 1.upto(5) do |i|
17
+ threads << Thread.new { Watirloo.browser(i) }
18
+ end
19
+ threads.each {|x| x.join}
20
+ end
21
+
22
+ it 'use locker to reattach to 5 browsers and load 5 diff pages at once' do
23
+ threads = []
24
+ files = ['census.html', 'labels.html', 'person.html', 'select_lists.html', 'radio_group.html']
25
+ titles = ['Census', 'Labels', 'Person', 'select lists', "radio_groups"]
26
+ 1.upto(5) do |i|
27
+ threads << Thread.new do
28
+ Watirloo.browser(i).goto testfile(files[i-1])
29
+ sleep 5 #add safety
30
+ Watirloo.browser(i).title.should == titles[i-1]
31
+ end
32
+ end
33
+ threads.each {|x| x.join}
34
+ end
35
+
36
+ it "reattach and close all 5 browsers" do
37
+ hwnds = Watirloo::Desktop.hwnds
38
+ threads =[]
39
+ 1.upto(5) { |i| threads << Thread.new { Watirloo.browser(i).close } }
40
+ threads.each {|x| x.join}
41
+ sleep 5 #Ensure browsers close
42
+ Watirloo::Desktop.deletions(hwnds).size.should == 5
43
+ end
44
+ end
45
+
@@ -0,0 +1,136 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe 'browser checkbox_group accesses a group of checkboxes sharing the same name on a page' do
4
+
5
+ before :each do
6
+ @browser = Watirloo::browser
7
+ @browser.goto testfile('checkbox_group1.html')
8
+ end
9
+
10
+ it 'browser responds to checkbox_group' do
11
+ @browser.should respond_to(:checkbox_group)
12
+ end
13
+
14
+ it 'access by name as default returns CheckboxGroup' do
15
+ if @browser.kind_of?(FireWatir::Firefox)
16
+ @browser.checkbox_group('pets').should be_kind_of(FireWatir::CheckboxGroup)
17
+ elsif @browser.kind_of?(Watir::IE)
18
+ @browser.checkbox_group('pets').should be_kind_of(Watir::CheckboxGroup)
19
+ end
20
+ end
21
+
22
+ it 'size retuns checkboxes as items count in a group' do
23
+ @browser.checkbox_group(:name, 'pets').size.should == 5
24
+ end
25
+
26
+ it 'values returns array of value attributes for each checkbox in a group' do
27
+ @browser.checkbox_group('pets').values.should == ["cat", "dog", "zook", "zebra", "wumpa"]
28
+ end
29
+
30
+ end
31
+
32
+ describe "checkbox_group values when no checkbox is checked in a group" do
33
+
34
+ before :each do
35
+ @browser = Watirloo::browser
36
+ @browser.goto testfile('checkbox_group1.html')
37
+ end
38
+
39
+
40
+ it 'selected should return nil' do
41
+ @browser.checkbox_group('pets').selected.should be_nil
42
+ end
43
+ it 'selected_value should return nil' do
44
+ @browser.checkbox_group('pets').selected_value.should be_nil
45
+ end
46
+ it 'selected_values should return empty array' do
47
+ @browser.checkbox_group('pets').selected_values.should be_empty
48
+ end
49
+
50
+ it "set? should return false when no checkbox is checked in a group" do
51
+ @browser.checkbox_group("pets").should_not be_set
52
+ end
53
+
54
+ end
55
+
56
+ describe "checkbox_group values when set string selecs one item only" do
57
+
58
+ before :each do
59
+ @browser = Watirloo::browser
60
+ @browser.goto testfile('checkbox_group1.html')
61
+ end
62
+
63
+
64
+ it "selected should return the string used to select it" do
65
+ @browser.checkbox_group('pets').set 'dog'
66
+ @browser.checkbox_group('pets').selected.should == 'dog'
67
+ end
68
+
69
+ it "selected_value should return the string when one item is selected" do
70
+ @browser.checkbox_group('pets').set 'dog'
71
+ @browser.checkbox_group('pets').selected_value.should == 'dog'
72
+ end
73
+
74
+ it 'selected values returns array with one element' do
75
+ @browser.checkbox_group('pets').set 'dog'
76
+ @browser.checkbox_group('pets').selected_values.should == ['dog']
77
+ end
78
+
79
+ it "set? should return truee when 1 checkbox is checked in a group" do
80
+ @browser.checkbox_group('pets').set 'dog'
81
+ @browser.checkbox_group("pets").should be_set
82
+ end
83
+
84
+ end
85
+
86
+
87
+ describe "checkbox_group set array of strings selects multiple values in a group" do
88
+
89
+ before :each do
90
+ @browser = Watirloo::browser
91
+ @browser.goto testfile('checkbox_group1.html')
92
+ end
93
+
94
+
95
+ it "selected returns array of strings when multiple values are selected" do
96
+ @browser.checkbox_group('pets').set ['dog', 'zebra', 'cat'] # not in order
97
+ @browser.checkbox_group('pets').selected.should == ['cat', 'dog', 'zebra']
98
+ end
99
+
100
+ it 'selected_value returns the same array of strings by position in a group' do
101
+ @browser.checkbox_group('pets').set ['zebra', 'dog', 'cat'] # not in order
102
+ @browser.checkbox_group('pets').selected_value.should == ['cat', 'dog', 'zebra'] # bypass filter
103
+ end
104
+
105
+ it "selected_values returns the same array of strings by position in a group" do
106
+ @browser.checkbox_group('pets').set ['cat', 'zebra', 'dog'] # not in order
107
+ @browser.checkbox_group('pets').selected_values.should == ['cat', 'dog', 'zebra']
108
+ end
109
+
110
+ it "set? should return truee when more than 1 checkbox is checked in a group" do
111
+ @browser.checkbox_group('pets').set ['cat', 'zebra', 'dog'] # not in order
112
+ @browser.checkbox_group("pets").should be_set
113
+ end
114
+
115
+ end
116
+
117
+ describe "checkbox_group set by numberical position" do
118
+
119
+ before :each do
120
+ @browser = Watirloo::browser
121
+ @browser.goto testfile('checkbox_group1.html')
122
+ end
123
+
124
+
125
+ it 'set Fixnum checks checkbox by position in a group. Position is 1 based.' do
126
+ #Behaves like select by single value
127
+ @browser.checkbox_group('pets').set 3
128
+ @browser.checkbox_group('pets').selected_value.should == 'zook'
129
+ end
130
+
131
+ it 'set array of Fixnums checks each checkbox by position' do
132
+ #behaves like select multiple strings
133
+ @browser.checkbox_group('pets').set [4,1,2] # not in order
134
+ @browser.checkbox_group('pets').selected.should == ["cat", "dog", "zebra"]
135
+ end
136
+ end
@@ -0,0 +1,55 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe 'checkbox_groups access for browser' do
4
+
5
+ before :each do
6
+ @browser = Watirloo::browser
7
+ @browser.goto testfile('checkbox_group1.html')
8
+ end
9
+
10
+ it 'browser responds to checkbox_group' do
11
+ @browser.should respond_to(:checkbox_groups)
12
+ end
13
+
14
+ it 'returns group object and its values from the page' do
15
+ @browser.checkbox_groups.should be_kind_of(Watir::CheckboxGroups)
16
+ end
17
+
18
+ it 'lenght returns integer count of groups' do
19
+ @browser.checkbox_groups.length.should == 4
20
+ end
21
+
22
+ it 'each iterator returns CheckboxGroup' do
23
+ @browser.checkbox_groups.each do |cbg|
24
+ cbg.should be_kind_of( Watir::CheckboxGroup )
25
+ end
26
+ end
27
+
28
+ it 'each accesses the group and returns name' do
29
+ names =[]
30
+ @browser.checkbox_groups.each do |cg|
31
+ names << cg.name
32
+ end
33
+ names.should == ['pets', 'singleIndicator', 'petsa', 'singleIndicatora']
34
+ end
35
+
36
+ it 'bracket access[] returns 1-based indexed group' do
37
+ @browser.checkbox_groups[1].values.should == %w[cat dog zook zebra wumpa]
38
+ @browser.checkbox_groups[3].name.should == 'petsa'
39
+ end
40
+
41
+ it 'if checkbox group does not exists it returns size 0 or name nil (or should it blow up? or respond to exists? method' do
42
+ @browser.checkbox_groups[6].size.should == 0 # does not exist. let's not blow up. suggestions?
43
+ @browser.checkbox_groups[6].name.should == nil #suggestions?
44
+ end
45
+
46
+ it 'return checkbox groups contained by the form element' do
47
+ @browser.forms[2].checkbox_groups.length.should == 2
48
+ names =[]
49
+ @browser.forms[2].checkbox_groups.each do |cbg|
50
+ names << cbg.name
51
+ end
52
+ names.should == ['petsa', 'singleIndicatora']
53
+ end
54
+
55
+ end