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