rwebspec-webdriver 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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