operawatir 0.3-jruby → 0.3.2-jruby
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.
- data/Gemfile +6 -2
- data/LICENSE +1 -1
- data/Rakefile +7 -8
- data/VERSION +1 -1
- data/bin/desktopwatir +3 -0
- data/bin/operawatir +2 -2
- data/lib/operadriver/webdriver-opera.jar +0 -0
- data/lib/operawatir.rb +14 -8
- data/lib/operawatir/browser.rb +49 -38
- data/lib/operawatir/compat/collection.rb +6 -0
- data/lib/operawatir/compat/element.rb +5 -2
- data/lib/operawatir/compat/element_finders.rb +19 -0
- data/lib/operawatir/desktop-waiter.rb +144 -0
- data/lib/operawatir/desktop_browser.rb +506 -0
- data/lib/operawatir/desktop_common.rb +111 -0
- data/lib/operawatir/desktop_container.rb +252 -0
- data/lib/operawatir/desktop_enums.rb +42 -0
- data/lib/operawatir/desktop_exceptions.rb +16 -0
- data/lib/operawatir/element.rb +6 -6
- data/lib/operawatir/exceptions.rb +3 -0
- data/lib/operawatir/keys.rb +116 -0
- data/lib/operawatir/platform.rb +59 -0
- data/lib/operawatir/quickwidgets.rb +3 -0
- data/lib/operawatir/quickwidgets/quick_addressfield.rb +23 -0
- data/lib/operawatir/quickwidgets/quick_button.rb +151 -0
- data/lib/operawatir/quickwidgets/quick_checkbox.rb +58 -0
- data/lib/operawatir/quickwidgets/quick_dialogtab.rb +23 -0
- data/lib/operawatir/quickwidgets/quick_dropdown.rb +27 -0
- data/lib/operawatir/quickwidgets/quick_editfield.rb +115 -0
- data/lib/operawatir/quickwidgets/quick_label.rb +12 -0
- data/lib/operawatir/quickwidgets/quick_radiobutton.rb +11 -0
- data/lib/operawatir/quickwidgets/quick_searchfield.rb +25 -0
- data/lib/operawatir/quickwidgets/quick_tab.rb +66 -0
- data/lib/operawatir/quickwidgets/quick_thumbnail.rb +26 -0
- data/lib/operawatir/quickwidgets/quick_toolbar.rb +11 -0
- data/lib/operawatir/quickwidgets/quick_treeitem.rb +157 -0
- data/lib/operawatir/quickwidgets/quick_treeview.rb +27 -0
- data/lib/operawatir/quickwidgets/quick_widget.rb +369 -0
- data/lib/operawatir/quickwidgets/quick_window.rb +150 -0
- data/lib/operawatir/selector.rb +1 -1
- data/lib/operawatir/version.rb +0 -1
- data/lib/operawatir/window.rb +9 -0
- data/operawatir.gemspec +382 -0
- data/spec/new_watirspec/browser_spec.rb +279 -0
- data/spec/new_watirspec/clipboard_spec.rb +79 -0
- data/spec/new_watirspec/collection_spec.rb +387 -0
- data/spec/new_watirspec/element_spec.rb +456 -0
- data/spec/new_watirspec/guards.rb +39 -0
- data/spec/new_watirspec/keys_spec.rb +206 -0
- data/spec/new_watirspec/server.rb +91 -0
- data/spec/new_watirspec/watirspec_helper.rb +62 -0
- data/spec/new_watirspec/window_spec.rb +370 -0
- data/utils/launchers/launcher-mac +0 -0
- metadata +191 -28
- data/.gitmodules +0 -3
@@ -34,5 +34,8 @@ module OperaWatir::Exceptions
|
|
34
34
|
|
35
35
|
# Raised when trying to access a table cell that doesn't exist.
|
36
36
|
class UnknownCellException < OperaWatirException; end
|
37
|
+
|
38
|
+
# Raised when pressing a modifier key that doesn't exist.
|
39
|
+
class InvalidKeyException < OperaWatirException; end
|
37
40
|
|
38
41
|
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class OperaWatir::Keys
|
3
|
+
|
4
|
+
attr_accessor :browser
|
5
|
+
|
6
|
+
def initialize(browser)
|
7
|
+
self.browser = browser
|
8
|
+
end
|
9
|
+
|
10
|
+
# Holds down supplied arbitrary list of keys indefinitely.
|
11
|
+
#
|
12
|
+
# @param [Symbol, String] *args Arbitrary list of symbols
|
13
|
+
# (modification keys) or strings (regular keys) to be pressed
|
14
|
+
# down.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# browser.keys.down 'a'
|
18
|
+
# browser.keys.down 'a', :right
|
19
|
+
#
|
20
|
+
# @seealso up
|
21
|
+
# @seealso send
|
22
|
+
def down(*args)
|
23
|
+
args.each { |key| driver.keyDown(key) }
|
24
|
+
end
|
25
|
+
|
26
|
+
# Depresses supplied arbitrary list of keys.
|
27
|
+
#
|
28
|
+
# @param [Symbol, String] *args Arbitrary list of symbols
|
29
|
+
# (modification keys) or strings (regular keys) to be depressed.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# browser.keys.up 'a', :right
|
33
|
+
#
|
34
|
+
# @seealso release
|
35
|
+
def up(*args)
|
36
|
+
args.each { |key| driver.keyUp(key) }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Releases all pressed down keys.
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# browser.keys.down :control, :shift, 'a'
|
43
|
+
# browser.keys.release
|
44
|
+
def release
|
45
|
+
driver.releaseKeys
|
46
|
+
end
|
47
|
+
|
48
|
+
# Presses an arbitrary list of keys or key combinations. Provided
|
49
|
+
# arguments are performed in sequence.
|
50
|
+
#
|
51
|
+
# Symbols are parsed as modification keys (such as :control, :shift,
|
52
|
+
# :backspace, &c.), arraysd are interpreted as key combinations
|
53
|
+
# (e.g. [:control, 'a'] will perform the combination C-a), and
|
54
|
+
# strings will be typed as regular words.
|
55
|
+
#
|
56
|
+
# Note that this method is not OS indepdendent in the sense that
|
57
|
+
# even though OS X does not have Control keys, it will not replace
|
58
|
+
# your sent keys with Command.
|
59
|
+
#
|
60
|
+
# Available modification keys: control, shift, access …
|
61
|
+
# TODO
|
62
|
+
#
|
63
|
+
# @param [Symbol, Array, String] *list Arbitrary list of symbols,
|
64
|
+
# arrays or strings which will form a sequence of keys to be
|
65
|
+
# pressed.
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# browser.keys.send 'a'
|
69
|
+
# browser.keys.send 'foo', 'bar'
|
70
|
+
# browser.keys.send :control
|
71
|
+
# browser.keys.send [:control, 'a']
|
72
|
+
# browser.keys.send [:control, 'a'], :backspace
|
73
|
+
def send(*list) # TODO rename?
|
74
|
+
list.each do |item|
|
75
|
+
case item
|
76
|
+
when Array
|
77
|
+
item.each_with_index do |key, index|
|
78
|
+
case key
|
79
|
+
when :access
|
80
|
+
access_key item[index + 1]
|
81
|
+
when Symbol
|
82
|
+
down key
|
83
|
+
else
|
84
|
+
key key
|
85
|
+
release
|
86
|
+
end
|
87
|
+
end
|
88
|
+
when Symbol
|
89
|
+
key item
|
90
|
+
else
|
91
|
+
type item
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def driver
|
99
|
+
browser.driver
|
100
|
+
end
|
101
|
+
|
102
|
+
def key(key)
|
103
|
+
driver.key key
|
104
|
+
end
|
105
|
+
|
106
|
+
def type(text)
|
107
|
+
driver.type text
|
108
|
+
end
|
109
|
+
|
110
|
+
def access_key(key)
|
111
|
+
driver.operaAction 'Enter access key mode'
|
112
|
+
send key
|
113
|
+
driver.operaAction 'Leave access key mode'
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
class OperaWatir::Platform
|
4
|
+
def self.launcher
|
5
|
+
return ENV['OPERA_LAUNCHER'] if ENV['OPERA_LAUNCHER']
|
6
|
+
|
7
|
+
path = case os
|
8
|
+
when :windows
|
9
|
+
raise Exceptions::NotImplementedException, 'only 32-bit windows supported' if bitsize == 64
|
10
|
+
'utils/launchers/launcher-win32-i86pc.exe'
|
11
|
+
when :linux
|
12
|
+
postfix = bitsize == 64 ? 'x86_64' : 'i686'
|
13
|
+
"utils/launchers/launcher-linux-#{postfix}"
|
14
|
+
when :macosx
|
15
|
+
'utils/launchers/launcher-mac'
|
16
|
+
end
|
17
|
+
|
18
|
+
if path
|
19
|
+
File.join(root, path)
|
20
|
+
else
|
21
|
+
raise Exceptions::NotImplementedException, "no known launcher for #{os.inspect}, set OPERA_LAUNCHER to override"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.opera
|
27
|
+
ENV['OPERA_PATH']
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.args
|
31
|
+
ENV['OPERA_ARGS'] || ''
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.os
|
35
|
+
@os ||= (
|
36
|
+
host_os = RbConfig::CONFIG['host_os']
|
37
|
+
case host_os
|
38
|
+
when /mswin|msys|mingw|bccwin|wince|emc/
|
39
|
+
:windows
|
40
|
+
when /darwin|mac os/
|
41
|
+
:macosx
|
42
|
+
when /linux/
|
43
|
+
:linux
|
44
|
+
when /solaris|bsd/
|
45
|
+
:unix
|
46
|
+
else
|
47
|
+
raise Exceptions::NotImplementedException, "#{host_os.inspect} not supported"
|
48
|
+
end
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.bitsize
|
53
|
+
ENV_JAVA['sun.arch.data.model'].to_i
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.root
|
57
|
+
@root ||= File.expand_path('../../..', __FILE__)
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,3 @@
|
|
1
|
+
%w(quick_widget quick_button quick_checkbox quick_editfield
|
2
|
+
quick_dropdown quick_dialogtab quick_label quick_radiobutton quick_treeview quick_addressfield
|
3
|
+
quick_searchfield quick_toolbar quick_window quick_tab quick_treeitem quick_thumbnail).each {|widget| require "operawatir/quickwidgets/#{widget}"}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module OperaWatir
|
2
|
+
class QuickAddressField < QuickEditField
|
3
|
+
|
4
|
+
# Checks the type of the widget is correct
|
5
|
+
#
|
6
|
+
# @private
|
7
|
+
def correct_type?
|
8
|
+
@element.getType == WIDGET_ENUM_MAP[:addressfield]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Enters the url into the address field, and waits for page loading
|
12
|
+
# to finish
|
13
|
+
#
|
14
|
+
# @param [String] URL to load
|
15
|
+
# @return [String] text in the address field after the page is loaded
|
16
|
+
# or a blank string
|
17
|
+
def load_page_with_url(url)
|
18
|
+
# Enters text in a field and then hits enter
|
19
|
+
enter_text_and_hit_enter(url)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module OperaWatir
|
2
|
+
class QuickButton < QuickWidget
|
3
|
+
|
4
|
+
# @private
|
5
|
+
# Checks the type of the widget is correct
|
6
|
+
def correct_type?
|
7
|
+
@element.getType == WIDGET_ENUM_MAP[:button]
|
8
|
+
end
|
9
|
+
|
10
|
+
######################################################################
|
11
|
+
# Checks if the button is the default button
|
12
|
+
#
|
13
|
+
# @return [Boolean] true if the default button otherwise false
|
14
|
+
#
|
15
|
+
def default?
|
16
|
+
element.isDefault
|
17
|
+
end
|
18
|
+
|
19
|
+
######################################################################
|
20
|
+
# Clicks the button, and waits for the window with window name
|
21
|
+
# win_name to be shown
|
22
|
+
#
|
23
|
+
# @param [String] win_name name of the window that will be opened (Pass a blank string for any window)
|
24
|
+
#
|
25
|
+
# @return [int] Window ID of the window shown or 0 if no window is shown
|
26
|
+
#
|
27
|
+
# @raise [DesktopExceptions::WidgetNotVisibleException] if the button
|
28
|
+
# is not visible
|
29
|
+
#
|
30
|
+
def open_window_with_click(win_name)
|
31
|
+
wait_start
|
32
|
+
click
|
33
|
+
wait_for_window_shown(win_name)
|
34
|
+
end
|
35
|
+
|
36
|
+
alias_method :open_dialog_with_click, :open_window_with_click
|
37
|
+
|
38
|
+
######################################################################
|
39
|
+
# Clicks the button, and waits for the dialog wizard to switch
|
40
|
+
# to the next page
|
41
|
+
#
|
42
|
+
# @return [int] Window ID of the dialog wizard or 0 if no window is shown
|
43
|
+
#
|
44
|
+
# @raise [DesktopExceptions::WidgetNotVisibleException] if the button
|
45
|
+
# is not visible
|
46
|
+
#
|
47
|
+
def change_page_with_click()
|
48
|
+
wait_start
|
49
|
+
click
|
50
|
+
wait_for_window_shown("")
|
51
|
+
end
|
52
|
+
|
53
|
+
######################################################################
|
54
|
+
# Clicks the button, and waits for the window with window name
|
55
|
+
# win_name to closed
|
56
|
+
#
|
57
|
+
# @param [String] win_name name of the window that will be closed (Pass a blank string for any window)
|
58
|
+
#
|
59
|
+
# @return [int] Window ID of the window is closed or 0 if no window is closed
|
60
|
+
#
|
61
|
+
# @raise [DesktopExceptions::WidgetNotVisibleException] if the button
|
62
|
+
# is not visible
|
63
|
+
#
|
64
|
+
def close_window_with_click(win_name)
|
65
|
+
wait_start
|
66
|
+
click
|
67
|
+
wait_for_window_close(win_name)
|
68
|
+
end
|
69
|
+
|
70
|
+
alias_method :close_dialog_with_click, :close_window_with_click
|
71
|
+
|
72
|
+
######################################################################
|
73
|
+
# Clicks the button, and waits for loading to finish
|
74
|
+
#
|
75
|
+
# @return [int] Window ID of the window shown or 0 if no window is shown
|
76
|
+
#
|
77
|
+
# @raise [DesktopExceptions::WidgetNotVisibleException] if the button
|
78
|
+
# is not visible
|
79
|
+
#
|
80
|
+
def load_page_with_click
|
81
|
+
wait_start
|
82
|
+
click()
|
83
|
+
# Just wait for the load
|
84
|
+
wait_for_window_loaded("")
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
######################################################################
|
89
|
+
# Clicks a button or expand control and toggles it state
|
90
|
+
#
|
91
|
+
# @return [int] the new state of the button or expand control,
|
92
|
+
# 0 for not pressed, or 1 for pressed
|
93
|
+
#
|
94
|
+
# @raise [DesktopExceptions::WidgetNotVisibleException] if the button
|
95
|
+
# is not visible
|
96
|
+
#
|
97
|
+
def toggle_with_click
|
98
|
+
click
|
99
|
+
|
100
|
+
# Cheat since we don't have an event yet
|
101
|
+
sleep(0.1)
|
102
|
+
|
103
|
+
element(true).getValue
|
104
|
+
end
|
105
|
+
|
106
|
+
######################################################################
|
107
|
+
# Clicks button to close the toolbar
|
108
|
+
#
|
109
|
+
# @raise [DesktopExceptions::WidgetNotVisibleException] if the button
|
110
|
+
# is not visible
|
111
|
+
#
|
112
|
+
def close_toolbar_with_click
|
113
|
+
click
|
114
|
+
|
115
|
+
# Cheat since we don't have an event yet
|
116
|
+
sleep(0.1)
|
117
|
+
end
|
118
|
+
|
119
|
+
alias_method :close_panel_with_click, :close_toolbar_with_click
|
120
|
+
|
121
|
+
def expand_with_click
|
122
|
+
click
|
123
|
+
sleep(0.1)
|
124
|
+
#No refresh element because it might not be there still (after click):)
|
125
|
+
end
|
126
|
+
|
127
|
+
alias_method :collapse_with_click, :expand_with_click
|
128
|
+
|
129
|
+
######################################################################
|
130
|
+
# Gets the value of the button or expand control.
|
131
|
+
#
|
132
|
+
# @return [int] 0 if not pressed, or 1 if pressed
|
133
|
+
#
|
134
|
+
# @raise [Exceptions::UnknownObjectException] if the widget could not be found
|
135
|
+
# using the specified method
|
136
|
+
def value
|
137
|
+
element.getValue
|
138
|
+
end
|
139
|
+
|
140
|
+
######################################################################
|
141
|
+
# Pauses to wait for security dialogs when buttons are not active
|
142
|
+
# right away on opening
|
143
|
+
#
|
144
|
+
# @return [Boolean] Returns true if the button becomes active
|
145
|
+
#
|
146
|
+
def wait_for_enabled
|
147
|
+
wait_for_widget_enabled
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module OperaWatir
|
2
|
+
class QuickCheckbox < QuickWidget
|
3
|
+
|
4
|
+
# @private
|
5
|
+
# Checks the type of the widget is correct
|
6
|
+
def correct_type?
|
7
|
+
@element.getType == WIDGET_ENUM_MAP[:checkbox]
|
8
|
+
end
|
9
|
+
|
10
|
+
######################################################################
|
11
|
+
# Checks if the checkbox is checked
|
12
|
+
#
|
13
|
+
# @return [Boolean] true if the checkbox is checked otherwise false
|
14
|
+
#
|
15
|
+
# @raise [Exceptions::UnknownObjectException] if the widget could not be found
|
16
|
+
# using the specified method
|
17
|
+
def checked?
|
18
|
+
element.isSelected
|
19
|
+
end
|
20
|
+
|
21
|
+
######################################################################
|
22
|
+
# Clicks a radio button or checkbox and toggles it state
|
23
|
+
#
|
24
|
+
# @return [int] the new state of the radio button or checkbox,
|
25
|
+
# false for not checked, or true for checked
|
26
|
+
#
|
27
|
+
# @raise [DesktopExceptions::WidgetNotVisibleException] if the checkbox
|
28
|
+
# is not visible
|
29
|
+
#
|
30
|
+
def toggle_with_click
|
31
|
+
click
|
32
|
+
|
33
|
+
# Cheat since we don't have an even yet
|
34
|
+
sleep(0.1)
|
35
|
+
|
36
|
+
element(true).isSelected
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
######################################################################
|
41
|
+
# Clicks the checkbox, and waits for the window with window name
|
42
|
+
# win_name to be shown
|
43
|
+
#
|
44
|
+
# @param [String] win_name name of the window that will be opened (Pass a blank string for any window)
|
45
|
+
#
|
46
|
+
# @return [int] Window ID of the window shown or 0 if no window is shown
|
47
|
+
#
|
48
|
+
# @raise [DesktopExceptions::WidgetNotVisibleException] if the checkbox
|
49
|
+
# is not visible
|
50
|
+
#
|
51
|
+
def open_dialog_with_click(win_name)
|
52
|
+
wait_start
|
53
|
+
click
|
54
|
+
wait_for_window_shown(win_name)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module OperaWatir
|
2
|
+
class QuickDialogTab < QuickWidget
|
3
|
+
|
4
|
+
# @private
|
5
|
+
# Checks the type of the widget is correct
|
6
|
+
def correct_type?
|
7
|
+
@element.getType == WIDGET_ENUM_MAP[:dialogtab]
|
8
|
+
end
|
9
|
+
|
10
|
+
######################################################################
|
11
|
+
# Switch to the dialog tab by clicking on it
|
12
|
+
#
|
13
|
+
# @raise [DesktopExceptions::WidgetNotVisibleException] if the dialogtab
|
14
|
+
# is not visible
|
15
|
+
#
|
16
|
+
def activate_tab_with_click
|
17
|
+
click
|
18
|
+
|
19
|
+
# No event yet so just cheat and sleep
|
20
|
+
sleep(0.1);
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|