osaka 0.3.0 → 0.3.1
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/lib/osaka/applicationwrapper.rb +45 -55
- data/lib/osaka/applicationwrapperexpectations.rb +42 -16
- data/lib/osaka/calculator.rb +1 -0
- data/lib/osaka/keynote.rb +1 -1
- data/lib/osaka/pages.rb +3 -6
- data/lib/osaka/scriptrunner.rb +3 -0
- data/lib/osaka/textedit.rb +0 -8
- data/lib/osaka/typicalapplication.rb +62 -19
- data/lib/osaka/version.rb +1 -1
- data/spec/applicationwrapper_spec.rb +33 -28
- data/spec/assets/01_first_slides.key +0 -0
- data/spec/assets/mail_merge_data.numbers +0 -0
- data/spec/assets/mail_merge_template.pages +0 -0
- data/spec/calculator_spec.rb +1 -0
- data/spec/integration_calculator_spec.rb +0 -1
- data/spec/integration_keynote_spec.rb +0 -1
- data/spec/integration_pages_numbers_mail_merge_spec.rb +1 -1
- data/spec/integration_textedit_spec.rb +3 -3
- data/spec/keynote_spec.rb +2 -2
- data/spec/pages_spec.rb +4 -4
- data/spec/textedit_spec.rb +1 -16
- data/spec/typicalapplication_spec.rb +102 -51
- metadata +2 -2
@@ -4,50 +4,6 @@ module Osaka
|
|
4
4
|
class InvalidLocation < RuntimeError
|
5
5
|
end
|
6
6
|
|
7
|
-
class ConditionProxy
|
8
|
-
|
9
|
-
def initialize(wrapper, action)
|
10
|
-
@wrapper = wrapper
|
11
|
-
@action = action
|
12
|
-
end
|
13
|
-
|
14
|
-
def create_condition_class_based_on_name(sym)
|
15
|
-
classname = "#{sym.to_s[0].upcase}#{sym.to_s[1..-1]}Condition"
|
16
|
-
eval(classname).new
|
17
|
-
end
|
18
|
-
|
19
|
-
def method_missing(sym, *args, &block)
|
20
|
-
condition = create_condition_class_based_on_name(sym)
|
21
|
-
@action.execute(@wrapper, condition, *args, &block)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class RepeatAction
|
26
|
-
def execute(wrapper, condition, *args, &block)
|
27
|
-
while (!CheckAction.new.execute(wrapper, condition, *args, &block))
|
28
|
-
yield unless block.nil?
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class CheckAction
|
34
|
-
def execute(wrapper, condition, *args, &block)
|
35
|
-
wrapper.system_event!("#{condition.as_script(wrapper, *args)};").strip == "true"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
class ExistsCondition
|
40
|
-
def as_script(wrapper, element_to_check)
|
41
|
-
"exists #{wrapper.construct_location(element_to_check)}"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class Not_existsCondition
|
46
|
-
def as_script(wrapper, element_to_check)
|
47
|
-
"not exists #{wrapper.construct_location(element_to_check)}"
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
7
|
class ApplicationWrapper
|
52
8
|
|
53
9
|
attr_reader :name
|
@@ -95,22 +51,51 @@ module Osaka
|
|
95
51
|
system_event!(event)
|
96
52
|
end
|
97
53
|
|
98
|
-
def
|
99
|
-
|
100
|
-
wait_until!
|
54
|
+
def exists(location)
|
55
|
+
system_event!("exists #{construct_location(location)}").strip == "true"
|
101
56
|
end
|
102
|
-
|
103
|
-
def
|
104
|
-
|
57
|
+
|
58
|
+
def not_exists(location)
|
59
|
+
system_event!("not exists #{construct_location(location)}").strip == "true"
|
60
|
+
end
|
61
|
+
|
62
|
+
def wait_until(locations, action)
|
63
|
+
while(true)
|
64
|
+
locations.flatten.each { |location|
|
65
|
+
return location if yield location
|
66
|
+
}
|
67
|
+
action.() unless action.nil?
|
68
|
+
end
|
105
69
|
end
|
106
70
|
|
107
|
-
|
71
|
+
def wait_until_exists(*locations)
|
72
|
+
activate
|
73
|
+
wait_until_exists!(locations)
|
74
|
+
end
|
108
75
|
|
109
|
-
def
|
110
|
-
|
76
|
+
def wait_until_exists!(*locations, &action)
|
77
|
+
wait_until(locations, action) { |location|
|
78
|
+
exists(location)
|
79
|
+
}
|
111
80
|
end
|
112
81
|
|
113
|
-
alias
|
82
|
+
alias until_exists wait_until_exists
|
83
|
+
alias until_exists! wait_until_exists!
|
84
|
+
|
85
|
+
def wait_until_not_exists(*locations, &action)
|
86
|
+
activate
|
87
|
+
wait_until_not_exists!(*locations, action)
|
88
|
+
end
|
89
|
+
|
90
|
+
def wait_until_not_exists!(*locations, &action)
|
91
|
+
wait_until(locations, action) { |location|
|
92
|
+
not_exists(location)
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
alias until_not_exists wait_until_not_exists
|
97
|
+
alias until_not_exists! wait_until_not_exists!
|
98
|
+
|
114
99
|
|
115
100
|
def construct_modifier_statement(modifier_keys)
|
116
101
|
modified_key_string = [ modifier_keys ].flatten.collect! { |mod_key| mod_key.to_s + " down"}.join(", ")
|
@@ -118,8 +103,13 @@ module Osaka
|
|
118
103
|
modifier_command
|
119
104
|
end
|
120
105
|
|
106
|
+
def construct_key_statement(key_keys)
|
107
|
+
return "return" if key_keys == :return
|
108
|
+
"\"#{key_keys}\""
|
109
|
+
end
|
110
|
+
|
121
111
|
def keystroke!(key, modifier_keys = [])
|
122
|
-
check_output( system_event!("keystroke
|
112
|
+
check_output( system_event!("keystroke #{construct_key_statement(key)}#{construct_modifier_statement(modifier_keys)}"), "keystroke")
|
123
113
|
self
|
124
114
|
end
|
125
115
|
|
@@ -1,22 +1,37 @@
|
|
1
1
|
|
2
2
|
module Osaka
|
3
3
|
module ApplicationWrapperExpectations
|
4
|
-
|
5
|
-
def
|
6
|
-
|
4
|
+
|
5
|
+
def expect_clone
|
6
|
+
@wrapper.should_receive(:clone)
|
7
|
+
end
|
8
|
+
|
9
|
+
def expect_activate
|
10
|
+
@wrapper.should_receive(:activate)
|
11
|
+
end
|
12
|
+
|
13
|
+
def expect_focus
|
14
|
+
@wrapper.should_receive(:focus)
|
15
|
+
end
|
16
|
+
|
17
|
+
def expect_set_current_window(name)
|
18
|
+
@wrapper.should_receive(:set_current_window).with(name)
|
7
19
|
end
|
8
20
|
|
9
|
-
def
|
10
|
-
|
21
|
+
def expect_running?
|
22
|
+
@wrapper.should_receive(:running?)
|
11
23
|
end
|
12
24
|
|
13
|
-
def
|
14
|
-
|
25
|
+
def expect_quit
|
26
|
+
@wrapper.should_receive(:quit)
|
15
27
|
end
|
16
28
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
29
|
+
def expect_window_list
|
30
|
+
@wrapper.should_receive(:window_list)
|
31
|
+
end
|
32
|
+
|
33
|
+
def expect_set(element, location, value)
|
34
|
+
@wrapper.should_receive(:set).with(element, location, value)
|
20
35
|
end
|
21
36
|
|
22
37
|
def expect_keystroke(key, modifier = [])
|
@@ -49,13 +64,24 @@ module Osaka
|
|
49
64
|
@wrapper.should_receive(:system_event).with(event)
|
50
65
|
end
|
51
66
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
67
|
+
def expect_exists(location)
|
68
|
+
@wrapper.should_receive(:exists).with(location)
|
69
|
+
end
|
70
|
+
|
71
|
+
def expect_wait_until_exists(location)
|
72
|
+
@wrapper.should_receive(:wait_until_exists).with(location)
|
73
|
+
end
|
74
|
+
|
75
|
+
def expect_wait_until_exists!(*location)
|
76
|
+
@wrapper.should_receive(:wait_until_exists!).with(*location)
|
77
|
+
end
|
78
|
+
|
79
|
+
def expect_wait_until_not_exists(location)
|
80
|
+
@wrapper.should_receive(:wait_until_not_exists).with(location)
|
57
81
|
end
|
58
|
-
|
59
82
|
|
83
|
+
def expect_until_not_exists!(element)
|
84
|
+
@wrapper.should_receive(:until_not_exists!).with(element).and_yield
|
85
|
+
end
|
60
86
|
end
|
61
87
|
end
|
data/lib/osaka/calculator.rb
CHANGED
data/lib/osaka/keynote.rb
CHANGED
@@ -16,7 +16,7 @@ module Osaka
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def select_all_slides
|
19
|
-
if @wrapper.
|
19
|
+
if @wrapper.exists(at.button("Slides").group(1).outline(1).scroll_area(2).splitter_group(1).splitter_group(1))
|
20
20
|
@wrapper.click(at.button("Slides").group(1).outline(1).scroll_area(2).splitter_group(1).splitter_group(1))
|
21
21
|
else
|
22
22
|
@wrapper.click(at.button("Slides").group(1).outline(1).scroll_area(1).splitter_group(1).splitter_group(1))
|
data/lib/osaka/pages.rb
CHANGED
@@ -11,7 +11,7 @@ module Osaka
|
|
11
11
|
def merge
|
12
12
|
@wrapper.click!(at.button("Merge").sheet(1))
|
13
13
|
print_dialog_location = 'window "Print"'
|
14
|
-
@wrapper.
|
14
|
+
@wrapper.wait_until_exists!("menu button \"PDF\" of #{print_dialog_location}")
|
15
15
|
TypicalPrintDialog.new(print_dialog_location, @wrapper)
|
16
16
|
end
|
17
17
|
|
@@ -26,7 +26,7 @@ module Osaka
|
|
26
26
|
private
|
27
27
|
def set_merge_to_document_printer(value)
|
28
28
|
@wrapper.click(at.pop_up_button(2).sheet(1))
|
29
|
-
@wrapper.
|
29
|
+
@wrapper.wait_until_exists!(at.menu_item(value).menu(1).pop_up_button(2).sheet(1))
|
30
30
|
@wrapper.click!(at.menu_item(value).menu(1).pop_up_button(2).sheet(1))
|
31
31
|
end
|
32
32
|
end
|
@@ -39,10 +39,7 @@ module Osaka
|
|
39
39
|
|
40
40
|
def mail_merge
|
41
41
|
@wrapper.click_menu_bar(at.menu_item(20), "Edit")
|
42
|
-
|
43
|
-
# @wrapper.wait_until.exists(at.menu(1).menu_bar_item("Edit").menu_bar(1))
|
44
|
-
# @wrapper.click!(at.menu_item(20).menu(1).menu_bar_item("Edit").menu_bar(1))
|
45
|
-
@wrapper.wait_until.exists(at.button("Merge").sheet(1))
|
42
|
+
@wrapper.wait_until_exists(at.button("Merge").sheet(1))
|
46
43
|
PagesMailMergeDialog.new(at.sheet(1), @wrapper)
|
47
44
|
end
|
48
45
|
|
data/lib/osaka/scriptrunner.rb
CHANGED
data/lib/osaka/textedit.rb
CHANGED
@@ -8,14 +8,6 @@ module Osaka
|
|
8
8
|
@wrapper = ApplicationWrapper.new("TextEdit")
|
9
9
|
end
|
10
10
|
|
11
|
-
def activate
|
12
|
-
super
|
13
|
-
if (@wrapper.current_window_name.empty?)
|
14
|
-
wait_for_new_window([])
|
15
|
-
@wrapper.set_current_window(@wrapper.window_list[0])
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
11
|
def type(text)
|
20
12
|
@wrapper.keystroke(text)
|
21
13
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
module Osaka
|
3
3
|
|
4
4
|
class TypicalSaveDialog
|
@@ -15,13 +15,13 @@ module Osaka
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def set_folder(pathname)
|
18
|
-
@wrapper.keystroke("g", [ :command, :shift ]).
|
18
|
+
@wrapper.keystroke("g", [ :command, :shift ]).wait_until_exists(at.sheet(1) + @self_location)
|
19
19
|
@wrapper.set("value", at.text_field(1).sheet(1) + @self_location, pathname)
|
20
|
-
@wrapper.click(at.button("Go").sheet(1) + @self_location).
|
20
|
+
@wrapper.click(at.button("Go").sheet(1) + @self_location).wait_until_not_exists(at.sheet(1) + @self_location)
|
21
21
|
end
|
22
22
|
|
23
23
|
def click_save
|
24
|
-
@wrapper.click(at.button("Save") + @self_location).
|
24
|
+
@wrapper.click(at.button("Save") + @self_location).wait_until_not_exists(@self_location)
|
25
25
|
end
|
26
26
|
|
27
27
|
def save(filename)
|
@@ -45,15 +45,18 @@ module Osaka
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def save_as_pdf(filename)
|
48
|
-
@wrapper.click!(at.menu_button("PDF") + @parent).
|
49
|
-
@wrapper.click!(at.menu_item(2).menu(1).menu_button("PDF") + @parent)
|
50
|
-
|
48
|
+
@wrapper.click!(at.menu_button("PDF") + @parent).wait_until_exists!(at.menu(1).menu_button("PDF") + @parent)
|
49
|
+
@wrapper.click!(at.menu_item(2).menu(1).menu_button("PDF") + @parent)
|
50
|
+
|
51
|
+
save_location = @wrapper.wait_until_exists!(at.window("Save"), at.sheet(1).window("Print"))
|
52
|
+
save_dialog = create_save_dialog(save_location, @wrapper)
|
51
53
|
save_dialog.save(filename)
|
52
54
|
|
53
|
-
@wrapper.
|
55
|
+
@wrapper.until_not_exists!(@parent) {
|
54
56
|
# Weird, but sometimes the dialog "hangs around" and clicking this checkbox will make it go away.
|
55
57
|
# Anyone who knows a better solution, please let me know!
|
56
|
-
|
58
|
+
# This is for snow leopard
|
59
|
+
@wrapper.click!(at.checkbox(1) + @parent) if @wrapper.exists(at.checkbox(1) + @parent)
|
57
60
|
}
|
58
61
|
end
|
59
62
|
end
|
@@ -77,6 +80,11 @@ module Osaka
|
|
77
80
|
@wrapper = ApplicationWrapper.new(name)
|
78
81
|
end
|
79
82
|
|
83
|
+
def initialize_copy(other)
|
84
|
+
super
|
85
|
+
@wrapper = other.wrapper.clone
|
86
|
+
end
|
87
|
+
|
80
88
|
def get_info
|
81
89
|
script_info = @wrapper.tell("get info for (path to application \"#{@name}\")")
|
82
90
|
ApplicationInfo.new(script_info)
|
@@ -90,7 +98,7 @@ module Osaka
|
|
90
98
|
|
91
99
|
def wait_for_window_and_dialogs_to_close(option)
|
92
100
|
if (option != :user_chose)
|
93
|
-
@wrapper.
|
101
|
+
@wrapper.until_not_exists!(@wrapper.current_window_location) {
|
94
102
|
close_dialog_sheet_with_dont_save
|
95
103
|
}
|
96
104
|
end
|
@@ -105,8 +113,8 @@ module Osaka
|
|
105
113
|
end
|
106
114
|
|
107
115
|
def close_dialog_sheet_with_dont_save
|
108
|
-
if (@wrapper.
|
109
|
-
@wrapper.click!(at.button(
|
116
|
+
if (@wrapper.exists(at.sheet(1)))
|
117
|
+
@wrapper.click!(at.button("Don’t Save").sheet(1))
|
110
118
|
end
|
111
119
|
end
|
112
120
|
|
@@ -117,8 +125,10 @@ module Osaka
|
|
117
125
|
end
|
118
126
|
end
|
119
127
|
|
120
|
-
def
|
121
|
-
|
128
|
+
def do_and_wait_for_new_window
|
129
|
+
@wrapper.activate
|
130
|
+
latest_window_list = original_window_list = @wrapper.window_list
|
131
|
+
yield
|
122
132
|
while (original_window_list == latest_window_list)
|
123
133
|
latest_window_list = @wrapper.window_list
|
124
134
|
end
|
@@ -126,22 +136,55 @@ module Osaka
|
|
126
136
|
end
|
127
137
|
|
128
138
|
def new_document
|
129
|
-
|
130
|
-
|
131
|
-
|
139
|
+
@wrapper.set_current_window(do_and_wait_for_new_window {
|
140
|
+
@wrapper.keystroke("n", :command)
|
141
|
+
})
|
132
142
|
@wrapper.focus
|
133
143
|
end
|
134
144
|
|
145
|
+
def duplicate_available?
|
146
|
+
@wrapper.exists(at.menu_item("Duplicate").menu(1).menu_bar_item("File").menu_bar(1))
|
147
|
+
end
|
148
|
+
|
149
|
+
def duplicate
|
150
|
+
unless duplicate_available?
|
151
|
+
raise(Osaka::VersioningError, "MacOS Versioning Error: Duplicate is not available on this Mac version")
|
152
|
+
end
|
153
|
+
new_window = do_and_wait_for_new_window {
|
154
|
+
@wrapper.keystroke("s", [:command, :shift])
|
155
|
+
}
|
156
|
+
new_instance = clone
|
157
|
+
new_instance.wrapper.set_current_window(do_and_wait_for_new_window {
|
158
|
+
@wrapper.keystroke!(:return)
|
159
|
+
})
|
160
|
+
|
161
|
+
new_instance
|
162
|
+
end
|
163
|
+
|
135
164
|
def save
|
136
165
|
@wrapper.keystroke("s", :command)
|
137
166
|
end
|
138
167
|
|
168
|
+
def save_pops_up_dialog?
|
169
|
+
@wrapper.exists(at.menu_item("Save…").menu(1).menu_bar_item("File").menu_bar(1))
|
170
|
+
end
|
171
|
+
|
139
172
|
def save_dialog
|
140
|
-
|
173
|
+
if save_pops_up_dialog?
|
174
|
+
save
|
175
|
+
@wrapper.wait_until_exists(at.sheet(1))
|
176
|
+
else
|
177
|
+
@wrapper.keystroke("s", [:command, :shift]).wait_until_exists(at.sheet(1))
|
178
|
+
end
|
141
179
|
create_save_dialog(at.sheet(1))
|
142
180
|
end
|
143
181
|
|
144
182
|
def save_as(filename)
|
183
|
+
if duplicate_available?
|
184
|
+
new_instance = duplicate
|
185
|
+
close
|
186
|
+
@wrapper = new_instance.wrapper.clone
|
187
|
+
end
|
145
188
|
dialog = save_dialog
|
146
189
|
dialog.save(filename)
|
147
190
|
@wrapper.set_current_window(File.basename(filename))
|
@@ -189,7 +232,7 @@ module Osaka
|
|
189
232
|
end
|
190
233
|
|
191
234
|
def print_dialog
|
192
|
-
@wrapper.keystroke("p", :command).
|
235
|
+
@wrapper.keystroke("p", :command).wait_until_exists(at.sheet(1))
|
193
236
|
create_print_dialog(at.sheet(1))
|
194
237
|
end
|
195
238
|
|
data/lib/osaka/version.rb
CHANGED
@@ -84,29 +84,37 @@ describe "Osaka::ApplicationWrapper" do
|
|
84
84
|
subject.system_event("quit")
|
85
85
|
end
|
86
86
|
|
87
|
-
it "Should be able to check whether a
|
88
|
-
Osaka::ScriptRunner.should_receive(:execute).with(/exists
|
89
|
-
subject.
|
87
|
+
it "Should be able to check whether a location exists" do
|
88
|
+
Osaka::ScriptRunner.should_receive(:execute).with(/exists button 1/).and_return("true\n")
|
89
|
+
subject.exists(at.button(1)).should == true
|
90
|
+
end
|
91
|
+
|
92
|
+
it "Should be able to check whether a location does not exists" do
|
93
|
+
Osaka::ScriptRunner.should_receive(:execute).with(/not exists window 1/).and_return("true\n")
|
94
|
+
subject.not_exists(at.window(1)).should == true
|
90
95
|
end
|
91
96
|
|
92
|
-
it "Should be able to wait
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
(counter == 5).to_s
|
97
|
-
}
|
98
|
-
subject.wait_until!.exists(at.window(1))
|
97
|
+
it "Should be able to wait until multiple locations exists and return the one that happened" do
|
98
|
+
subject.should_receive(:exists).with(at.button(1)).and_return(false, false, false)
|
99
|
+
subject.should_receive(:exists).with(at.sheet(5)).and_return(false, false, true)
|
100
|
+
subject.wait_until_exists!(at.button(1), at.sheet(5)).should == at.sheet(5)
|
99
101
|
end
|
100
102
|
|
101
103
|
it "Should be able to wait until exists and activate the application first" do
|
102
104
|
subject.should_receive(:activate)
|
103
|
-
|
104
|
-
subject.
|
105
|
+
subject.should_receive(:wait_until_exists!).with([at.window(1)])
|
106
|
+
subject.wait_until_exists(at.window(1))
|
105
107
|
end
|
106
108
|
|
109
|
+
it "Should be able to wait for a specific element and activate" do
|
110
|
+
subject.should_receive(:activate)
|
111
|
+
subject.should_receive(:wait_until_not_exists!).with(at.window(1), nil)
|
112
|
+
subject.wait_until_not_exists(at.window(1))
|
113
|
+
end
|
114
|
+
|
107
115
|
it "Should be able to wait for a specific element to not exist anymore" do
|
108
|
-
|
109
|
-
subject.
|
116
|
+
subject.should_receive(:not_exists).with(at.window(1)).and_return(false, false, true)
|
117
|
+
subject.wait_until_not_exists!(at.window(1))
|
110
118
|
end
|
111
119
|
|
112
120
|
it "Should be able to generate keystroke events" do
|
@@ -114,6 +122,11 @@ describe "Osaka::ApplicationWrapper" do
|
|
114
122
|
subject.keystroke!("p")
|
115
123
|
end
|
116
124
|
|
125
|
+
it "Should be able to generate return keystroke event" do
|
126
|
+
Osaka::ScriptRunner.should_receive(:execute).with(/keystroke return/).and_return("")
|
127
|
+
subject.keystroke!(:return)
|
128
|
+
end
|
129
|
+
|
117
130
|
it "Prints a warning when keystroke results in some outputShould be able to generate keystroke events" do
|
118
131
|
check_for_warning("keystroke")
|
119
132
|
subject.keystroke!("p")
|
@@ -139,7 +152,7 @@ describe "Osaka::ApplicationWrapper" do
|
|
139
152
|
it "Should be able to do a keystroke and wait until something happen in one easy line" do
|
140
153
|
Osaka::ScriptRunner.should_receive(:execute).with(/keystroke "p"/).and_return("")
|
141
154
|
Osaka::ScriptRunner.should_receive(:execute).with(/exists window 1/).and_return("true")
|
142
|
-
subject.keystroke!("p", []).
|
155
|
+
subject.keystroke!("p", []).wait_until_exists!(at.window(1))
|
143
156
|
end
|
144
157
|
|
145
158
|
it "Should be able to keystroke_and_wait_until_exists and activate" do
|
@@ -147,7 +160,7 @@ describe "Osaka::ApplicationWrapper" do
|
|
147
160
|
subject.should_receive(:focus)
|
148
161
|
Osaka::ScriptRunner.should_receive(:execute).with(/keystroke "p"/).and_return("")
|
149
162
|
Osaka::ScriptRunner.should_receive(:execute).with(/exists window 1/).and_return("true")
|
150
|
-
subject.keystroke("p", []).
|
163
|
+
subject.keystroke("p", []).wait_until_exists!(at.window(1))
|
151
164
|
end
|
152
165
|
|
153
166
|
it "Should be able to do clicks" do
|
@@ -164,14 +177,14 @@ describe "Osaka::ApplicationWrapper" do
|
|
164
177
|
it "Should be able to do clicks and wait until something happened in one easy line" do
|
165
178
|
Osaka::ScriptRunner.should_receive(:execute).with(/click/).and_return("")
|
166
179
|
Osaka::ScriptRunner.should_receive(:execute).with(/exists window 1/).and_return("true")
|
167
|
-
subject.click!("button").
|
180
|
+
subject.click!("button").wait_until_exists!(at.window(1))
|
168
181
|
end
|
169
182
|
|
170
183
|
it "Should be able to click_and_wait_until_exists and activate" do
|
171
184
|
subject.should_receive(:activate)
|
172
185
|
Osaka::ScriptRunner.should_receive(:execute).with(/click/).and_return("")
|
173
186
|
Osaka::ScriptRunner.should_receive(:execute).with(/exists window 1/).and_return("true")
|
174
|
-
subject.click("button").
|
187
|
+
subject.click("button").wait_until_exists!(at.window(1))
|
175
188
|
end
|
176
189
|
|
177
190
|
it "Should be able to click on menu bar items" do
|
@@ -224,17 +237,9 @@ describe "Osaka::ApplicationWrapper" do
|
|
224
237
|
end
|
225
238
|
|
226
239
|
it "Should be able to loop over some script until something happens" do
|
227
|
-
|
228
|
-
Osaka::ScriptRunner.should_receive(:execute).exactly(3).times.with(/exists window 1/).and_return {
|
229
|
-
counter = counter + 1
|
230
|
-
if counter > 2
|
231
|
-
"true"
|
232
|
-
else
|
233
|
-
"false"
|
234
|
-
end
|
235
|
-
}
|
240
|
+
Osaka::ScriptRunner.should_receive(:execute).and_return("false", "false", "true")
|
236
241
|
subject.should_receive(:activate).twice
|
237
|
-
subject.
|
242
|
+
subject.until_exists!(at.window(1)) {
|
238
243
|
subject.activate
|
239
244
|
}
|
240
245
|
end
|
Binary file
|
Binary file
|
Binary file
|
data/spec/calculator_spec.rb
CHANGED
@@ -40,6 +40,7 @@ describe "Mac GUI Calculator" do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it "Should be able to get the value from the screen" do
|
43
|
+
expect_wait_until_exists!(at.static_text(1).group(1))
|
43
44
|
@wrapper.should_receive(:get!).with("value", at.static_text(1).group(1)).and_return("0")
|
44
45
|
subject.result.should == "0"
|
45
46
|
end
|
@@ -4,7 +4,6 @@ require 'osaka'
|
|
4
4
|
describe "Integration tests for Keynote and Common Flows" do
|
5
5
|
|
6
6
|
it "Should be able to do a combine with just one file" do
|
7
|
-
|
8
7
|
assets_directory = File.join(File.dirname(__FILE__), "assets")
|
9
8
|
|
10
9
|
keynote_file = File.join(assets_directory, "01_first_slides.key")
|
@@ -4,7 +4,7 @@ require 'osaka'
|
|
4
4
|
describe "Integration of mail merge flow with Pages and Numbers" do
|
5
5
|
|
6
6
|
it "Should mail merge the assets and generate a PDF" do
|
7
|
-
|
7
|
+
|
8
8
|
assets_directory = File.join(File.dirname(__FILE__), "assets")
|
9
9
|
numbers_data = File.join(assets_directory, "mail_merge_data.numbers")
|
10
10
|
pages_template = File.join(assets_directory, "mail_merge_template.pages")
|
@@ -16,17 +16,17 @@ describe "Integration test using TextEdit" do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "can type in the window" do
|
19
|
-
subject.
|
19
|
+
subject.new_document
|
20
20
|
subject.type("Hello World")
|
21
21
|
subject.text.should == "Hello World"
|
22
|
+
subject.close(:dont_save)
|
22
23
|
end
|
23
24
|
|
24
25
|
it "can type in two windows using two instances" do
|
25
|
-
|
26
26
|
editor1 = subject
|
27
27
|
editor2 = Osaka::TextEdit.new
|
28
28
|
|
29
|
-
editor1.
|
29
|
+
editor1.new_document
|
30
30
|
editor2.new_document
|
31
31
|
|
32
32
|
editor1.type("Typing in window 1")
|
data/spec/keynote_spec.rb
CHANGED
@@ -17,7 +17,7 @@ describe "Osaka::Keynote" do
|
|
17
17
|
|
18
18
|
it "Should be possible to select all the slides in the default location" do
|
19
19
|
slides_button_location = at.button("Slides").group(1).outline(1).scroll_area(2).splitter_group(1).splitter_group(1)
|
20
|
-
|
20
|
+
expect_exists(slides_button_location).and_return(true)
|
21
21
|
expect_click(slides_button_location)
|
22
22
|
subject.should_receive(:select_all)
|
23
23
|
subject.select_all_slides
|
@@ -26,7 +26,7 @@ describe "Osaka::Keynote" do
|
|
26
26
|
it "Should be possible to select all the slides in the alternative location" do
|
27
27
|
slides_button_location = at.button("Slides").group(1).outline(1).scroll_area(2).splitter_group(1).splitter_group(1)
|
28
28
|
alternative_slides_button_location = at.button("Slides").group(1).outline(1).scroll_area(1).splitter_group(1).splitter_group(1)
|
29
|
-
|
29
|
+
expect_exists(slides_button_location).and_return(false)
|
30
30
|
expect_click(alternative_slides_button_location)
|
31
31
|
subject.should_receive(:select_all)
|
32
32
|
subject.select_all_slides
|
data/spec/pages_spec.rb
CHANGED
@@ -27,14 +27,14 @@ describe "Osaka::Pages" do
|
|
27
27
|
it "Should be able to select the Mail Merge" do
|
28
28
|
@wrapper.should_receive(:current_window_name).any_number_of_times.and_return("Pages.pages")
|
29
29
|
expect_click_menu_bar(at.menu_item(20), "Edit")
|
30
|
-
|
30
|
+
expect_wait_until_exists(at.button("Merge").sheet(1))
|
31
31
|
subject.mail_merge
|
32
32
|
end
|
33
33
|
|
34
34
|
it "Should click the merge button of the mail merge dialog" do
|
35
35
|
@wrapper.should_receive(:current_window_name).any_number_of_times.and_return("Pages.pages")
|
36
36
|
expect_click!(at.button("Merge").sheet(1))
|
37
|
-
|
37
|
+
expect_wait_until_exists!(at.menu_button("PDF").window("Print"))
|
38
38
|
subject.mail_merge.merge
|
39
39
|
end
|
40
40
|
end
|
@@ -52,14 +52,14 @@ describe "Osaka::Pages Mail Merge dialog" do
|
|
52
52
|
|
53
53
|
it "Should be able to set the mail merge dialog to merge to new document" do
|
54
54
|
expect_click(at.pop_up_button(2).sheet(1))
|
55
|
-
|
55
|
+
expect_wait_until_exists!(at.menu_item(1).menu(1).pop_up_button(2).sheet(1))
|
56
56
|
expect_click!(at.menu_item(1).menu(1).pop_up_button(2).sheet(1))
|
57
57
|
subject.set_merge_to_new_document
|
58
58
|
end
|
59
59
|
|
60
60
|
it "Should be able to set the mail merge dialog to merge to printer" do
|
61
61
|
expect_click(at.pop_up_button(2).sheet(1))
|
62
|
-
|
62
|
+
expect_wait_until_exists!(at.menu_item(2).menu(1).pop_up_button(2).sheet(1))
|
63
63
|
expect_click!(at.menu_item(2).menu(1).pop_up_button(2).sheet(1))
|
64
64
|
subject.set_merge_to_printer
|
65
65
|
end
|
data/spec/textedit_spec.rb
CHANGED
@@ -10,22 +10,7 @@ describe "TextEdit" do
|
|
10
10
|
before (:each) do
|
11
11
|
@wrapper = subject.wrapper = double("Osaka::ApplicationWrapper")
|
12
12
|
end
|
13
|
-
|
14
|
-
it "should set the window on activation" do
|
15
|
-
@wrapper.should_receive(:activate)
|
16
|
-
@wrapper.should_receive(:current_window_name).and_return("")
|
17
|
-
subject.should_receive(:wait_for_new_window).with([])
|
18
|
-
@wrapper.should_receive(:window_list).and_return(["Untitled"])
|
19
|
-
@wrapper.should_receive(:set_current_window).with("Untitled")
|
20
|
-
subject.activate
|
21
|
-
end
|
22
|
-
|
23
|
-
it "shouldn't set the window on activation when it is already set" do
|
24
|
-
@wrapper.should_receive(:activate)
|
25
|
-
@wrapper.should_receive(:current_window_name).and_return("Untitled")
|
26
|
-
subject.activate
|
27
|
-
end
|
28
|
-
|
13
|
+
|
29
14
|
it "Should be able to type some text" do
|
30
15
|
expect_keystroke('Hello World')
|
31
16
|
subject.type("Hello World")
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
2
|
require 'osaka'
|
3
3
|
|
4
4
|
describe "Osaka::TypicalApplication" do
|
@@ -16,80 +16,118 @@ describe "Osaka::TypicalApplication" do
|
|
16
16
|
Osaka::ScriptRunner.disable_debug_prints
|
17
17
|
end
|
18
18
|
|
19
|
+
it "Should be able to clone TypicalApplications" do
|
20
|
+
expect_clone
|
21
|
+
subject.clone
|
22
|
+
end
|
23
|
+
|
19
24
|
it "Should pass the right open string to the application osascript" do
|
20
25
|
filename = "filename.key"
|
21
26
|
expect_tell("open \"#{File.absolute_path(filename)}\"")
|
22
|
-
|
27
|
+
expect_set_current_window(filename)
|
23
28
|
subject.open(filename)
|
24
29
|
end
|
25
30
|
|
26
31
|
it "Should only get the basename of the filename when it sets the window title." do
|
27
32
|
filename = "/root/dirname/filename.key"
|
28
33
|
expect_tell("open \"#{File.absolute_path(filename)}\"")
|
29
|
-
|
34
|
+
expect_set_current_window("filename.key")
|
30
35
|
subject.open(filename)
|
31
36
|
end
|
32
37
|
|
33
38
|
it "Should be able to quit" do
|
34
|
-
|
35
|
-
|
39
|
+
expect_running?.and_return(true)
|
40
|
+
expect_quit
|
36
41
|
subject.quit
|
37
42
|
end
|
38
43
|
|
39
44
|
it "Should be able to check if its running" do
|
40
|
-
|
41
|
-
subject.running
|
45
|
+
expect_running?.and_return(true)
|
46
|
+
subject.running?.should == true
|
42
47
|
end
|
43
48
|
|
44
49
|
it "Won't quit when the application isn't running" do
|
45
|
-
|
50
|
+
expect_running?.and_return(false)
|
46
51
|
subject.quit(:dont_save)
|
47
52
|
end
|
48
53
|
|
49
54
|
it "Should be able to quit without saving" do
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
expect_click!(at.button(
|
55
|
+
expect_running?.and_return(true, true, false)
|
56
|
+
expect_quit
|
57
|
+
expect_exists(at.sheet(1)).and_return(true)
|
58
|
+
expect_click!(at.button("Don’t Save").sheet(1))
|
54
59
|
subject.quit(:dont_save)
|
55
60
|
end
|
56
61
|
|
57
|
-
it "Should be able to
|
58
|
-
subject.
|
59
|
-
subject.wait_for_new_window([])
|
60
|
-
end
|
61
|
-
|
62
|
-
it "Should be able to wait until a new window exists and it takes 4 calls" do
|
63
|
-
counter = 0
|
64
|
-
subject.wrapper.should_receive(:window_list).exactly(4).times.and_return(["new window"]) {
|
65
|
-
counter = counter + 1
|
66
|
-
counter.should <= 5 # Added here so that the test won't end up in an endless loop.
|
67
|
-
counter >= 4 ? [ "new window" ] : []
|
68
|
-
}
|
69
|
-
subject.wait_for_new_window([])
|
70
|
-
end
|
71
|
-
|
72
|
-
it "Should be able to create a new document" do
|
73
|
-
subject.wrapper.should_receive(:window_list)
|
62
|
+
it "Should be able to create a new document" do
|
63
|
+
subject.should_receive(:do_and_wait_for_new_window).and_yield.and_return("new_window")
|
74
64
|
expect_keystroke("n", :command)
|
75
|
-
|
76
|
-
|
77
|
-
subject.wrapper.should_receive(:focus)
|
65
|
+
expect_set_current_window("new_window")
|
66
|
+
expect_focus
|
78
67
|
subject.new_document
|
79
68
|
end
|
80
69
|
|
70
|
+
it "Should be able to do something and wait until a new window pops up" do
|
71
|
+
expect_window_list.and_return(["original window"], ["original window"], ["original window"], ["new window", "original window"])
|
72
|
+
expect_activate
|
73
|
+
code_block_called = false
|
74
|
+
subject.do_and_wait_for_new_window {
|
75
|
+
code_block_called = true
|
76
|
+
}.should == "new window"
|
77
|
+
code_block_called.should == true
|
78
|
+
end
|
79
|
+
|
81
80
|
it "Should be able to save" do
|
82
81
|
expect_keystroke("s", :command)
|
83
82
|
subject.save
|
84
83
|
end
|
85
84
|
|
86
|
-
it "Should be able to save as a file" do
|
85
|
+
it "Should be able to save as a file without duplicate being available" do
|
86
|
+
subject.should_receive(:duplicate_available?).and_return(false)
|
87
87
|
save_dialog = double("Osaka::TypicalSaveDialog")
|
88
88
|
subject.should_receive(:save_dialog).and_return(save_dialog)
|
89
89
|
save_dialog.should_receive(:save).with("filename")
|
90
|
-
|
90
|
+
expect_set_current_window("filename")
|
91
91
|
subject.save_as("filename")
|
92
92
|
end
|
93
|
+
|
94
|
+
it "Should be able to save as a file using the duplicate..." do
|
95
|
+
new_instance = mock(:TypicalApplication)
|
96
|
+
new_instance_wrapper = mock(:ApplicationWrapper)
|
97
|
+
save_dialog = double("Osaka::TypicalSaveDialog").as_null_object
|
98
|
+
|
99
|
+
subject.should_receive(:duplicate_available?).and_return(true)
|
100
|
+
subject.should_receive(:duplicate).and_return(new_instance)
|
101
|
+
new_instance.should_receive(:wrapper).and_return(new_instance_wrapper)
|
102
|
+
new_instance_wrapper.should_receive(:clone).and_return(@wrapper)
|
103
|
+
|
104
|
+
subject.should_receive(:close)
|
105
|
+
subject.should_receive(:save_dialog).and_return(save_dialog)
|
106
|
+
expect_set_current_window("filename")
|
107
|
+
subject.save_as("filename")
|
108
|
+
end
|
109
|
+
|
110
|
+
it "Should be able to check whether Duplicate is supported" do
|
111
|
+
expect_exists(at.menu_item("Duplicate").menu(1).menu_bar_item("File").menu_bar(1)).and_return(true)
|
112
|
+
subject.duplicate_available?.should == true
|
113
|
+
end
|
114
|
+
|
115
|
+
it "Should throw an exception when duplicate is not available"do
|
116
|
+
subject.should_receive(:duplicate_available?).and_return(false)
|
117
|
+
lambda {subject.duplicate}.should raise_error(Osaka::VersioningError, "MacOS Versioning Error: Duplicate is not available on this Mac version")
|
118
|
+
end
|
119
|
+
|
120
|
+
it "Should return a new keynote instance variable after duplication" do
|
121
|
+
new_instance = mock(:TypicalApplication)
|
122
|
+
subject.should_receive(:duplicate_available?).and_return(true)
|
123
|
+
subject.should_receive(:do_and_wait_for_new_window).and_yield.and_return("duplicate window", "New name duplicate window")
|
124
|
+
expect_keystroke("s", [:command, :shift])
|
125
|
+
subject.should_receive(:clone).and_return(new_instance)
|
126
|
+
new_instance.should_receive(:wrapper).and_return(@wrapper)
|
127
|
+
expect_keystroke!(:return)
|
128
|
+
expect_set_current_window("New name duplicate window")
|
129
|
+
subject.duplicate.should == new_instance
|
130
|
+
end
|
93
131
|
|
94
132
|
it "Should be able to close" do
|
95
133
|
expect_keystroke("w", :command)
|
@@ -103,12 +141,12 @@ describe "Osaka::TypicalApplication" do
|
|
103
141
|
end
|
104
142
|
|
105
143
|
it "Should be able to activate" do
|
106
|
-
|
144
|
+
expect_activate
|
107
145
|
subject.activate
|
108
146
|
end
|
109
147
|
|
110
148
|
it "Should be able to focus" do
|
111
|
-
|
149
|
+
expect_focus
|
112
150
|
subject.focus
|
113
151
|
end
|
114
152
|
|
@@ -134,19 +172,32 @@ describe "Osaka::TypicalApplication" do
|
|
134
172
|
|
135
173
|
it "Should be able to retrieve a print dialog" do
|
136
174
|
expect_keystroke("p", :command)
|
137
|
-
|
175
|
+
expect_wait_until_exists(at.sheet(1))
|
138
176
|
subject.print_dialog
|
139
177
|
end
|
140
178
|
|
141
|
-
it "Should be able to
|
179
|
+
it "Should be able to check whether the save will pop up a dialog or not" do
|
180
|
+
expect_exists(at.menu_item("Save…").menu(1).menu_bar_item("File").menu_bar(1)).and_return(true)
|
181
|
+
subject.save_pops_up_dialog?.should == true
|
182
|
+
end
|
183
|
+
|
184
|
+
it "Should be able to retrieve a save dialog by using save as" do
|
185
|
+
subject.should_receive(:save_pops_up_dialog?).and_return(false)
|
142
186
|
expect_keystroke("s", [:command, :shift])
|
143
|
-
|
187
|
+
expect_wait_until_exists(at.sheet(1))
|
144
188
|
subject.save_dialog
|
145
189
|
end
|
146
190
|
|
191
|
+
it "Should be able to retrieve a save dialog using duplicate and save" do
|
192
|
+
subject.should_receive(:save_pops_up_dialog?).and_return(true)
|
193
|
+
subject.should_receive(:save)
|
194
|
+
expect_wait_until_exists(at.sheet(1))
|
195
|
+
subject.save_dialog
|
196
|
+
end
|
197
|
+
|
147
198
|
describe "Application info" do
|
148
199
|
it "Should be able to retrieve an application info object and parse it" do
|
149
|
-
|
200
|
+
expect_tell('get info for (path to application "ApplicationName")').and_return('name:ApplicationName.app, creation date:date "Sunday, December 21, 2008 PM 06:14:11"}')
|
150
201
|
app_info = subject.get_info
|
151
202
|
app_info.name.should == "ApplicationName.app"
|
152
203
|
end
|
@@ -160,17 +211,17 @@ describe "Osaka::TypicalApplication" do
|
|
160
211
|
save_dialog_mock = double(:GenericSaveDialog)
|
161
212
|
|
162
213
|
expect_click!(at.menu_button("PDF").sheet(1))
|
163
|
-
|
214
|
+
expect_wait_until_exists!(at.menu(1).menu_button("PDF").sheet(1))
|
164
215
|
|
165
216
|
expect_click!(at.menu_item(2).menu(1).menu_button("PDF").sheet(1))
|
166
|
-
|
217
|
+
expect_wait_until_exists!(at.window("Save"), at.sheet(1).window("Print")).and_return(at.window("Save"))
|
167
218
|
|
168
219
|
subject.should_receive(:create_save_dialog).with(at.window("Save"), subject.wrapper).and_return(save_dialog_mock)
|
169
220
|
save_dialog_mock.should_receive(:save).with("filename")
|
170
221
|
|
171
|
-
|
172
|
-
|
173
|
-
|
222
|
+
expect_until_not_exists!(at.sheet(1))
|
223
|
+
expect_exists(at.checkbox(1).sheet(1)).and_return(true)
|
224
|
+
expect_click!(at.checkbox(1).sheet(1))
|
174
225
|
|
175
226
|
subject.save_as_pdf("filename")
|
176
227
|
end
|
@@ -202,7 +253,7 @@ describe "Osaka::TypicalApplication" do
|
|
202
253
|
end
|
203
254
|
|
204
255
|
it "Should set the path when a full path is given" do
|
205
|
-
|
256
|
+
@wrapper.as_null_object
|
206
257
|
subject.should_receive(:set_filename)
|
207
258
|
subject.should_receive(:set_folder).with("/path/second")
|
208
259
|
subject.save("/path/second/name")
|
@@ -210,21 +261,21 @@ describe "Osaka::TypicalApplication" do
|
|
210
261
|
|
211
262
|
it "Should be able to click save" do
|
212
263
|
expect_click(at.button("Save").sheet(1))
|
213
|
-
|
264
|
+
expect_wait_until_not_exists(at.sheet(1))
|
214
265
|
subject.click_save
|
215
266
|
end
|
216
267
|
|
217
268
|
it "Should be able to set the filename" do
|
218
|
-
|
269
|
+
@wrapper.should_receive(:set).with('value', at.text_field(1).sheet(1), "filename")
|
219
270
|
subject.set_filename("filename")
|
220
271
|
end
|
221
272
|
|
222
273
|
it "Should be able to set the path" do
|
223
274
|
expect_keystroke("g", [ :command, :shift ])
|
224
|
-
|
225
|
-
|
275
|
+
expect_wait_until_exists(at.sheet(1).sheet(1))
|
276
|
+
expect_set("value", at.text_field(1).sheet(1).sheet(1), "path")
|
226
277
|
expect_click(at.button("Go").sheet(1).sheet(1))
|
227
|
-
|
278
|
+
expect_wait_until_not_exists(at.sheet(1).sheet(1))
|
228
279
|
subject.set_folder("path")
|
229
280
|
end
|
230
281
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: osaka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.3.
|
5
|
+
version: 0.3.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Bas Vodde
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-07
|
13
|
+
date: 2012-08-07 00:00:00 +08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|