rwebspec-webdriver 0.1.1 → 0.1.2

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 (34) hide show
  1. data/Rakefile +11 -12
  2. data/lib/rwebspec-webdriver/assert.rb +445 -0
  3. data/lib/{rwebspec → rwebspec-webdriver}/clickJSDialog.rb +0 -0
  4. data/lib/{rwebspec → rwebspec-webdriver}/context.rb +13 -11
  5. data/lib/rwebspec-webdriver/database_checker.rb +76 -0
  6. data/lib/rwebspec-webdriver/driver.rb +1011 -0
  7. data/lib/rwebspec-webdriver/element_locator.rb +89 -0
  8. data/lib/rwebspec-webdriver/load_test_helper.rb +174 -0
  9. data/lib/{rwebspec → rwebspec-webdriver}/matchers/contains_text.rb +0 -0
  10. data/lib/rwebspec-webdriver/popup.rb +149 -0
  11. data/lib/rwebspec-webdriver/rspec_helper.rb +101 -0
  12. data/lib/rwebspec-webdriver/test_script.rb +10 -0
  13. data/lib/rwebspec-webdriver/test_utils.rb +219 -0
  14. data/lib/rwebspec-webdriver/testwise_plugin.rb +85 -0
  15. data/lib/rwebspec-webdriver/using_pages.rb +51 -0
  16. data/lib/rwebspec-webdriver/web_browser.rb +744 -0
  17. data/lib/rwebspec-webdriver/web_page.rb +110 -0
  18. data/lib/rwebspec-webdriver/web_testcase.rb +40 -0
  19. data/lib/rwebspec-webdriver.rb +12 -12
  20. metadata +22 -22
  21. data/lib/rwebspec/assert.rb +0 -443
  22. data/lib/rwebspec/database_checker.rb +0 -74
  23. data/lib/rwebspec/driver.rb +0 -1009
  24. data/lib/rwebspec/element_locator.rb +0 -87
  25. data/lib/rwebspec/load_test_helper.rb +0 -172
  26. data/lib/rwebspec/popup.rb +0 -147
  27. data/lib/rwebspec/rspec_helper.rb +0 -99
  28. data/lib/rwebspec/test_script.rb +0 -8
  29. data/lib/rwebspec/test_utils.rb +0 -217
  30. data/lib/rwebspec/testwise_plugin.rb +0 -83
  31. data/lib/rwebspec/using_pages.rb +0 -49
  32. data/lib/rwebspec/web_browser.rb +0 -742
  33. data/lib/rwebspec/web_page.rb +0 -108
  34. data/lib/rwebspec/web_testcase.rb +0 -38
@@ -0,0 +1,89 @@
1
+ module RWebSpec
2
+ module WebDriver
3
+
4
+ module ElementLocator
5
+
6
+ BUTTON_VALID_TYPES = %w[button reset submit image]
7
+ def button_elements
8
+ find_elements(:xpath, ".//button | .//input[#{attribute_expression :type => BUTTON_VALID_TYPES}]")
9
+ end
10
+
11
+ CHECK_BOX_TYPES = %w(checkbox)
12
+ def check_box_elements(how, what, opts = [])
13
+ find_elements(:xpath, ".//input[#{attribute_expression :type => CHECK_BOX_TYPES}]")
14
+ end
15
+
16
+ RADIO_TYPES = %w(radio)
17
+ def radio_elements(how, what, opts = [])
18
+ find_elements(:xpath, ".//input[#{attribute_expression :type => RADIO_TYPES}]")
19
+ end
20
+
21
+ def select_elements(how, what, opts = [])
22
+ find_elements(:xpath, ".//input[#{attribute_expression :type => RADIO_TYPES}]")
23
+ end
24
+
25
+ # TextField, TextArea
26
+ TEXT_FILED_TYPES = %w(text)
27
+ def text_field_elements
28
+ find_elements(:xpath, ".//input[#{attribute_expression :type => TEXT_FILED_TYPES}]")
29
+ end
30
+
31
+ def text_area_elements
32
+ find_elements(:xpath, ".//textarea")
33
+ end
34
+
35
+ FILE_FIELD_TYPES = %w(file)
36
+ def file_field_elements
37
+ find_elements(:xpath, ".//input[#{attribute_expression :type => FILE_FIELD_TYPES}]")
38
+ end
39
+
40
+ HIDDEN_TYPES = %w(hidden)
41
+ def hidden_elements
42
+ find_elements(:xpath, ".//input[#{attribute_expression :type => HIDDEN_TYPES}]")
43
+ end
44
+
45
+ #---
46
+ def find_by_tag(tag)
47
+ find_elements(:tag_name, tag)
48
+ end
49
+
50
+ def should_use_label_element?
51
+ @selector[:tag_name] != "option" rescue false
52
+ end
53
+
54
+ def equal_pair(key, value)
55
+ # we assume :label means a corresponding label element, not the attribute
56
+ if key == :label && should_use_label_element?
57
+ "@id=//label[normalize-space()='#{value}']/@for"
58
+ else
59
+ "#{lhs_for(key)}='#{value}'"
60
+ end
61
+ end
62
+
63
+ def lhs_for(key)
64
+ case key
65
+ when :text, 'text'
66
+ 'normalize-space()'
67
+ when :href
68
+ # TODO: change this behaviour?
69
+ 'normalize-space(@href)'
70
+ else
71
+ "@#{key.to_s.gsub("_", "-")}"
72
+ end
73
+ end
74
+
75
+
76
+ def attribute_expression(selectors)
77
+ selectors.map do |key, val|
78
+ if val.kind_of?(Array)
79
+ "(" + val.map { |v| equal_pair(key, v) }.join(" or ") + ")"
80
+ else
81
+ equal_pair(key, val)
82
+ end
83
+ end.join(" and ")
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,174 @@
1
+
2
+ module RWebSpec
3
+ module WebDriver
4
+ module LoadTestHelper
5
+
6
+ include RWebSpec::WebDriver::Utils
7
+ include RWebSpec::WebDriver::Assert
8
+
9
+ MAX_VU = 1000
10
+
11
+ # only support firefox or Celerity
12
+ def open_browser(base_url, options = {})
13
+ default_options = {:resynchronize => false, :firefox => false }
14
+ options = default_options.merge(options)
15
+ options[:firefox] ||= (ENV['LOADWISE_PREVIEW'] || $LOADWISE_PREVIEW)
16
+ RWebSpec::WebDriver::WebBrowser.new(base_url, nil, options)
17
+ end
18
+
19
+ # maybe attach_browser
20
+
21
+ # Does not provide real function, other than make enhancing test syntax
22
+ #
23
+ # Example:
24
+ # allow { click_button('Register') }
25
+ def allow(&block)
26
+ yield
27
+ end
28
+ alias shall_allow allow
29
+ alias allowing allow
30
+
31
+ # try operation, ignore if errors occur
32
+ #
33
+ # Example:
34
+ # failsafe { click_link("Logout") } # try logout, but it still OK if not being able to (already logout))
35
+ def failsafe(&block)
36
+ begin
37
+ yield
38
+ rescue =>e
39
+ end
40
+ end
41
+ alias fail_safe failsafe
42
+
43
+ # Try the operation up to specified timeout (in seconds), and sleep given interval (in seconds).
44
+ # Error will be ignored until timeout
45
+ # Example
46
+ # try { click_link('waiting')}
47
+ # try(10, 2) { click_button('Search' } # try to click the 'Search' button upto 10 seconds, try every 2 seconds
48
+ # try { click_button('Search' }
49
+ def try(timeout = @@default_timeout, polling_interval = @@default_polling_interval || 1, &block)
50
+ start_time = Time.now
51
+
52
+ last_error = nil
53
+ until (duration = Time.now - start_time) > timeout
54
+ begin
55
+ return if yield
56
+ last_error = nil
57
+ rescue => e
58
+ last_error = e
59
+ end
60
+ sleep polling_interval
61
+ end
62
+
63
+ raise "Timeout after #{duration.to_i} seconds with error: #{last_error}." if last_error
64
+ raise "Timeout after #{duration.to_i} seconds."
65
+ end
66
+ alias try_upto try
67
+
68
+ ##
69
+ # Convert :first to 1, :second to 2, and so on...
70
+ def symbol_to_sequence(symb)
71
+ value = { :zero => 0,
72
+ :first => 1,
73
+ :second => 2,
74
+ :third => 3,
75
+ :fourth => 4,
76
+ :fifth => 5,
77
+ :sixth => 6,
78
+ :seventh => 7,
79
+ :eighth => 8,
80
+ :ninth => 9,
81
+ :tenth => 10 }[symb]
82
+ return value || symb.to_i
83
+ end
84
+
85
+ # monitor current execution using
86
+ #
87
+ # Usage
88
+ # log_time { browser.click_button('Confirm') }
89
+ def log_time(msg, &block)
90
+ start_time = Time.now
91
+ yield
92
+ end_time = Time.now
93
+
94
+ Thread.current[:log] ||= []
95
+ Thread.current[:log] << {:file => File.basename(__FILE__),
96
+ :message => msg,
97
+ :start_time => Time.now,
98
+ :duration => Time.now - start_time}
99
+
100
+ if $LOADWISE_MONITOR
101
+ begin
102
+ require 'java'
103
+ puts "Calling Java 1"
104
+ java_import com.loadwise.db.MemoryDatabase
105
+ #puts "Calling Java 2: #{MemoryDatabase.count}"
106
+ MemoryDatabase.addEntry(1, "zdfa01", "a_spec.rb", msg, start_time, end_time);
107
+ puts "Calling Java Ok: #{MemoryDatabase.count}"
108
+ rescue NameError => ne
109
+ puts "Name Error: #{ne}"
110
+ # failed to load Java class
111
+ rescue => e
112
+ puts "Failed to calling Java: #{e.class.name}"
113
+ end
114
+ end
115
+ # How to notify LoadWise at real time
116
+ # LoadWise to collect CPU
117
+ end
118
+
119
+ def run_with_virtual_users(virtual_user_count = 2, preview = false, &block)
120
+ raise "too many virtual users" if virtual_user_count > MAX_VU
121
+
122
+ begin
123
+ if defined?(LOADWISE_PREVIEW)
124
+ preview = LOADWISE_PREVIEW
125
+ end
126
+ rescue => e1
127
+ end
128
+
129
+ if preview
130
+ virtual_user_count = 1
131
+ $LOADWISE_PREVIEW = true
132
+ end
133
+
134
+ if (virtual_user_count <= 1)
135
+ yield
136
+ else
137
+ threads = []
138
+ vu_reports = {}
139
+ virtual_user_count.times do |idx|
140
+ threads[idx] = Thread.new do
141
+ start_time = Time.now
142
+ vu_reports[idx] ||= []
143
+ begin
144
+ yield
145
+ vu_reports[idx] = Thread.current[:log]
146
+ rescue => e
147
+ vu_reports[idx] = Thread.current[:log]
148
+ vu_reports[idx] ||= []
149
+ vu_reports[idx] << { :error => e }
150
+ end
151
+ vu_reports[idx] ||= []
152
+ vu_reports[idx] << { :message => "Total Duration", :duration => Time.now - start_time }
153
+ puts "VU[#{idx+1}] #{Time.now - start_time}s"
154
+ end
155
+ end
156
+
157
+ threads.each {|t| t.join; }
158
+ vu_reports.each do |key, value|
159
+ value.each do |entry|
160
+ if entry[:error] then
161
+ puts "Error: #{entry[:error]}"
162
+ else
163
+ puts "[#{key}] #{entry[:message]}, #{entry[:duration]}"
164
+ end
165
+ end
166
+ end
167
+
168
+ return vu_reports
169
+ end
170
+ end
171
+
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,149 @@
1
+ module RWebSpec
2
+ module WebDriver
3
+ module Popup
4
+
5
+ #= Popup
6
+ #
7
+
8
+ # Start background thread to click popup windows
9
+ # Warning:
10
+ # Make browser window active
11
+ # Don't mouse your mouse to focus other window during test execution
12
+ def check_for_popups
13
+ autoit = WIN32OLE.new('AutoItX3.Control')
14
+ #
15
+ # Do forever - assumes popups could occur anywhere/anytime in your
16
+ # application.
17
+ loop do
18
+ # Look for window with given title. Give up after 1 second.
19
+ ret = autoit.WinWait('Windows Internet Explorer', '', 1)
20
+ #
21
+ # If window found, send appropriate keystroke (e.g. {enter}, {Y}, {N}).
22
+ if (ret==1) then
23
+ autoit.Send('{enter}')
24
+ end
25
+ #
26
+ # Take a rest to avoid chewing up cycles and give another thread a go.
27
+ # Then resume the loop.
28
+ sleep(3)
29
+ end
30
+ end
31
+
32
+ ##
33
+ # Check for "Security Information" and "Security Alert" alert popup, click 'Yes'
34
+ #
35
+ # Usage: For individual test suite
36
+ #
37
+ # before(:all) do
38
+ # $popup = Thread.new { check_for_alerts }
39
+ # open_in_browser
40
+ # ...
41
+ # end
42
+ #
43
+ # after(:all) do
44
+ # close_browser
45
+ # Thread.kill($popup)
46
+ # end
47
+ #
48
+ # or for all tests,
49
+ # $popup = Thread.new { check_for_alerts }
50
+ # at_exit{ Thread.kill($popup) }
51
+ def check_for_security_alerts
52
+ autoit = WIN32OLE.new('AutoItX3.Control')
53
+ loop do
54
+ ["Security Alert", "Security Information"].each do |win_title|
55
+ ret = autoit.WinWait(win_title, '', 1)
56
+ if (ret==1) then
57
+ autoit.Send('{Y}')
58
+ end
59
+ end
60
+ sleep(3)
61
+ end
62
+ end
63
+
64
+ def verify_alert(title = "Microsoft Internet Explorer", button = "OK")
65
+ if is_windows? && !is_firefox?
66
+ WIN32OLE.new('AutoItX3.Control').ControlClick(title, '', button)
67
+ else
68
+ raise "This function only supports IE"
69
+ end
70
+ end
71
+
72
+ def click_button_in_security_information_popup(button = "&Yes")
73
+ verify_alert("Security Information", "", button)
74
+ end
75
+ alias click_security_information_popup click_button_in_security_information_popup
76
+
77
+ def click_button_in_security_alert_popup(button = "&Yes")
78
+ verify_alert("Security Alert", "", button)
79
+ end
80
+ alias click_security_alert_popup click_button_in_security_alert_popup
81
+
82
+ def click_button_in_javascript_popup(button = "OK")
83
+ verify_alert()
84
+ end
85
+ alias click_javascript_popup click_button_in_javascript_popup
86
+
87
+ ##
88
+ # This only works for IEs
89
+ # Cons:
90
+ # - Slow
91
+ # - only works in IE
92
+ # - does not work for security alert ?
93
+ def ie_popup_clicker(button_name = "OK", max_wait = 15)
94
+ require 'watir/contrib/enabled_popup'
95
+ require 'win32ole'
96
+ hwnd = ie.enabled_popup(15)
97
+ if (hwnd) #yeah! a popup
98
+ popup = WinClicker.new
99
+ popup.makeWindowActive(hwnd) #Activate the window.
100
+ popup.clickWindowsButton_hwnd(hwnd, button_name) #Click the button
101
+ #popup.clickWindowsButton(/Internet/,button_name,30)
102
+ popup = nil
103
+ end
104
+ end
105
+
106
+ def click_popup_window(button, wait_time= 9, user_input=nil )
107
+ @web_browser.start_clicker(button, wait_time, user_input)
108
+ sleep 0.5
109
+ end
110
+ # run a separate process waiting for the popup window to click
111
+ #
112
+ #
113
+ def prepare_to_click_button_in_popup(button = "OK", wait_time = 3)
114
+ # !@web_browser.is_firefox?
115
+ # TODO: firefox is OK
116
+ if RUBY_PLATFORM =~ /mswin/ || RUBY_PLATFORM =~ /mingw/ then
117
+ start_checking_js_dialog(button, wait_time)
118
+ else
119
+ raise "this only support on Windows and on IE"
120
+ end
121
+ end
122
+
123
+ # Start a background process to click the button on a javascript popup window
124
+ def start_checking_js_dialog(button = "OK", wait_time = 3)
125
+ w = WinClicker.new
126
+ longName = File.expand_path(File.dirname(__FILE__)).gsub("/", "\\" )
127
+ shortName = w.getShortFileName(longName)
128
+ c = "start ruby #{shortName}\\clickJSDialog.rb #{button} #{wait_time} "
129
+ w.winsystem(c)
130
+ w = nil
131
+ end
132
+
133
+ # Click the button in javascript popup dialog
134
+ # Usage:
135
+ # click_button_in_popup_after { click_link('Cancel')}
136
+ # click_button_in_popup_after("OK") { click_link('Cancel')}
137
+ #
138
+ def click_button_in_popup_after(options = {:button => "OK", :wait_time => 3}, &block)
139
+ if is_windows? then
140
+ start_checking_js_dialog(options[:button], options[:wait_time])
141
+ yield
142
+ else
143
+ raise "this only support on Windows and on IE"
144
+ end
145
+ end
146
+
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,101 @@
1
+ require 'uri'
2
+ require File.dirname(__FILE__) + "/driver"
3
+ require File.dirname(__FILE__) + "/web_page"
4
+ require File.dirname(__FILE__) + "/assert"
5
+
6
+ # ZZ patches to RSpec 1.1.2 - 1.1.4
7
+ # - add to_s method to example_group
8
+ module Spec
9
+ module Example
10
+ class ExampleGroup
11
+ def to_s
12
+ @_defined_description
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ # example
19
+ # should link_by_text(text, options).size > 0
20
+
21
+ module RWebSpec
22
+ module WebDriver
23
+ module RSpecHelper
24
+ include RWebSpec::WebDriver::Driver
25
+ include RWebSpec::WebDriver::Assert
26
+ include RWebSpec::WebDriver::Utils
27
+
28
+ # --
29
+ # Content
30
+ # --
31
+
32
+ def table_source(table_id)
33
+ table(:id, table_id).innerHTML
34
+ # elem = @web_browser.document.getElementById(table_id)
35
+ # raise "The element '#{table_id}' is not a table or there are multple elements with same id" unless elem.name.uppercase == "TABLE"
36
+ # elem.innerHTML
37
+ end
38
+ alias table_source_by_id table_source
39
+
40
+ def element_text(elem_id)
41
+ @web_browser.element_value(elem_id)
42
+ end
43
+ alias element_text_by_id element_text
44
+
45
+ #TODO: is it working?
46
+ def element_source(elem_id)
47
+ @web_browser.get_html_in_element(elem_id)
48
+ end
49
+
50
+
51
+ def button_by_id(button_id)
52
+ button(:id, button_id)
53
+ end
54
+
55
+ def buttons_by_caption(text)
56
+ button(:text, text)
57
+ end
58
+ alias buttons_by_text buttons_by_caption
59
+
60
+ def link_by_id(link_id)
61
+ link(:id, link_id)
62
+ end
63
+
64
+ # default options: exact => true
65
+ def links_by_text(link_text, options = {})
66
+ options.merge!({:exact=> true})
67
+ matching_links = []
68
+ links.each { |link|
69
+ matching_links << link if (options[:exact] ? link.text == link_text : link.text.include?(link_text))
70
+ }
71
+ return matching_links
72
+ end
73
+ alias links_with_text links_by_text
74
+
75
+ def save_page(file_name = nil)
76
+ @web_browser.save_page(file_name)
77
+ end
78
+
79
+ def save_content_to_file(content, file_name = nil)
80
+ file_name ||= Time.now.strftime("%Y%m%d%H%M%S") + ".html"
81
+ puts "about to save page: #{File.expand_path(file_name)}"
82
+ File.open(file_name, "w").puts content
83
+ end
84
+
85
+ # When running
86
+ def debugging?
87
+ $ITEST2_DEBUGGING && $ITEST2_RUNNING_AS == "test_case"
88
+ end
89
+
90
+ # RSpec Matchers
91
+ #
92
+ # Example,
93
+ # a_number.should be_odd_number
94
+ def be_odd_number
95
+ simple_matcher("must be odd number") { |actual| actual && actual.to_id % 2 == 1}
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+ end