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
@@ -0,0 +1,140 @@
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
+ # provide browser for a client. If now browser is assigned to a client
16
+ # Use the default Watirloo.browser if no browser set explicitly
17
+ def browser
18
+ @browser ||= ::Watirloo.browser
19
+ end
20
+
21
+ # set browser instance for a client to use
22
+ # --
23
+ # the method is a bit better than browser= because setting browser in mehtods would probably
24
+ # requires a call to:
25
+ # self.browser= ie
26
+ # else
27
+ # browser = ie
28
+ # may be an assignemnt to local variable
29
+ def browser=(browser)
30
+ @browser = browser
31
+ end
32
+
33
+ # browser document container that delimits the scope of elements.
34
+ # all faces use page as a base. In a frameless DOM the browser is page, the document container.
35
+ # however if page with frames you can setup a doc destination to be a frame as the
36
+ # base container for face accessors.
37
+ # in most circumstances page is a passthru to browser
38
+ # example: if you have a frameset and you want to talk to a frame(:name, 'content') you can redefine
39
+ # set the page
40
+ # self.page = browser.frame(:name, 'content') see set_page
41
+ #
42
+ def page
43
+ @page ||= browser
44
+ end
45
+
46
+ # set the page base element as the receiver of all facename methods
47
+ # one would have to make this type of call:
48
+ # self.page = watir_element
49
+ # else this:
50
+ # page = watir_element
51
+ # may be treated as assignemnt to local variable
52
+ #
53
+ def page=(watir_element)
54
+ @page = watir_element
55
+ end
56
+
57
+ module ClassMethods
58
+
59
+ # "anything which is the forward or world facing part of a system
60
+ # which has internal structure is considered its 'face', like the facade of a building"
61
+ # ~ http://en.wikipedia.org/wiki/Face
62
+ #
63
+ # Declares Semantic Interface to the DOM elements on the Page (facade) binds a symbol to a block of code that accesses the DOM.
64
+ # When the user speaks of filling in the last name the are usually entering data in a text_field
65
+ # we can create a semantic accessor interface like this:
66
+ # face(:last_name) { text_field(:name, 'last_nm'}
67
+ # what matters to the user is on the left (:last_name) and what matters to the programmer is on the right
68
+ # The face method provides an adapter and insolates the tests form the changes in GUI.
69
+ # The patterns is: face(:friendlyname) { watir_element(how, whatcode }
70
+ # where watir_element is actuall way of accessing the element on the page. The page is implicit.
71
+ # Each interface or face is an object of interest that we want to access by its interface name
72
+ # example:
73
+ #
74
+ # class GoogleSearch
75
+ # include Watirloo::Page
76
+ # face(:query) { text_field(:name, 'q') }
77
+ # face(:search) { button(:name, 'btnG') }
78
+ # end
79
+ #
80
+ # at run time calling
81
+ # query.set "Ruby"
82
+ # is equivalent to
83
+ # page.text_field(:name, 'q').set "Ruby"
84
+ # where page is the root of HTML document
85
+ #
86
+ def face(name, *args, &definition)
87
+ define_method(name) do |*args|
88
+ page.instance_exec(*args, &definition)
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ # metahook by which ClassMethods become singleton methods of an including module
95
+ # Perhaps the proper way is to do this
96
+ # class SomeClass
97
+ # include PageHelper
98
+ # extend PageHelper::ClassMethods
99
+ # end
100
+ # but we are just learning this metaprogramming
101
+ def self.included(klass)
102
+ klass.extend(ClassMethods)
103
+ end
104
+
105
+ # enter values on controls idenfied by keys on the page.
106
+ # data map is a hash, key represents the page objects that can be filled or set with values,
107
+ # value represents its value to be set, either text, array or boolean
108
+ # exmaple:
109
+ # spray :first => "Johnny", :last => 'Begood'
110
+ #
111
+ # # Given the faces defined
112
+ # face(:first) {doc.text_field(:name, 'lst_nm')}
113
+ # face(:last) {doc.text_field(:name, 'fst_nm')}
114
+ def spray(hash)
115
+ hash.each_pair do |facename, value|
116
+ self.send(facename).set value #make every control element in watir respond to set
117
+ end
118
+ end
119
+
120
+ # set values on the page given the interface keys
121
+ alias set spray
122
+
123
+
124
+ def scrape(facenames)
125
+ data = {}
126
+ facenames.each do |facename|
127
+ watir_control = self.send facename
128
+ method_name = case watir_control.class.to_s.split("::").last
129
+ when "SelectList", "CheckboxGroup", "RadioGroup" then :selected
130
+ else
131
+ :value
132
+ end
133
+ data.update facename => watir_control.send(method_name)
134
+ end
135
+ data
136
+ end
137
+
138
+
139
+ end
140
+ end
data/lib/watirloo.rb ADDED
@@ -0,0 +1,16 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'watirloo/extension/object'
5
+ require 'watirloo/extension/watir_ducktape'
6
+ require 'watirloo/extension/watir_reflector'
7
+ require 'watirloo/browsers'
8
+ require 'watirloo/desktop'
9
+ require 'watirloo/locker'
10
+ require 'watirloo/page'
11
+
12
+ module Watirloo
13
+ VERSION = '0.0.6' # Jul2009
14
+
15
+ end
16
+
@@ -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
@@ -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) { checkbox(:name, 'pets', 'cat') }
10
+ face(:pets_dog) { checkbox(:name, 'pets', 'dog') }
11
+ face(:pets_zook) { checkbox(:name, 'pets', 'zook') }
12
+ face(:pets_zebra) { checkbox(:name, 'pets', 'zebra') }
13
+ face(:pets_wumpa) { 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