osaka 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,411 @@
1
+
2
+ require 'osaka'
3
+
4
+ describe "Osaka::RemoteControl" do
5
+
6
+ include(*Osaka::OsakaExpectations)
7
+
8
+ name = "ApplicationName"
9
+
10
+ subject { Osaka::RemoteControl.new(name) }
11
+ let(:control) { subject }
12
+
13
+ before (:each) do
14
+ Osaka::ScriptRunner.enable_debug_prints
15
+ end
16
+
17
+ after (:each) do
18
+ Osaka::ScriptRunner.disable_debug_prints
19
+ end
20
+
21
+
22
+ def expect_execute_and_warning_for(action)
23
+ expect_execute_osascript.and_return("An Error")
24
+ subject.should_receive(:puts).with(/#{action}/)
25
+ end
26
+
27
+ it "Should be able to print warning messages" do
28
+ subject.should_receive(:puts).with("Osaka WARNING while doing ThisAction: Message")
29
+ subject.print_warning("ThisAction", "Message")
30
+ end
31
+
32
+ context "Query things from the OS" do
33
+
34
+ it "Should be possible to check whether an application is still running" do
35
+ expect_execute_osascript("tell application \"System Events\"; (name of processes) contains \"#{name}\"; end tell").and_return("false")
36
+ subject.running?.should be_false
37
+ end
38
+
39
+ it "Can get the OS version (lion)" do
40
+ expect_execute_osascript("system version of (system info)").and_return("10.7.4\n")
41
+ subject.mac_version.should == :lion
42
+ subject.mac_version_string.should == "10.7.4"
43
+ end
44
+
45
+ it "Can get the OS version (mountain lion)" do
46
+ expect_execute_osascript("system version of (system info)").and_return("10.8\n")
47
+ subject.mac_version.should == :mountain_lion
48
+ end
49
+
50
+ it "Can get the OS version (snow leopard)" do
51
+ expect_execute_osascript("system version of (system info)").and_return("10.6\n")
52
+ subject.mac_version.should == :snow_leopard
53
+ end
54
+
55
+ it "Can get the OS version (snow leopard)" do
56
+ expect_execute_osascript("system version of (system info)").and_return("1\n")
57
+ subject.mac_version.should == :other
58
+ end
59
+ end
60
+
61
+ context "Able to compare different remote controls" do
62
+
63
+ it "Should be able to clone controls" do
64
+ subject.set_current_window "Window"
65
+ new_control = subject.clone
66
+ new_control.should == subject
67
+ new_control.should_not equal(subject)
68
+ end
69
+
70
+ it "Should be having different current window instances when cloning" do
71
+ subject.set_current_window "Window"
72
+ new_control = subject.clone
73
+ new_control.set_current_window "Not the same"
74
+ subject.current_window_name.should_not == new_control.current_window_name
75
+
76
+ end
77
+
78
+ it "Should be able to compare objects using names" do
79
+ subject.should == Osaka::RemoteControl.new(name)
80
+ subject.should_not == Osaka::RemoteControl.new("otherName")
81
+ end
82
+
83
+ it "Should be able to compare objects using window" do
84
+ equal_object = Osaka::RemoteControl.new(name)
85
+ unequal_object = Osaka::RemoteControl.new(name)
86
+ equal_object.set_current_window("Window")
87
+ subject.set_current_window("Window")
88
+ unequal_object.set_current_window "Another Window"
89
+
90
+ subject.should == equal_object
91
+ subject.should_not == unequal_object
92
+ end
93
+ end
94
+
95
+ context "Basic control functionality of telling and sending system events" do
96
+
97
+ quoted_name = "\"#{name}\""
98
+
99
+ it "Should be able to tell applications to do something" do
100
+ expect_execute_osascript("tell application #{quoted_name}; command; end tell")
101
+ subject.tell("command")
102
+ end
103
+
104
+ it "Can also pass multi-line commands to telling an application what to do" do
105
+ expect_execute_osascript("tell application #{quoted_name}; command1; command2; end tell")
106
+ subject.tell("command1; command2")
107
+ end
108
+
109
+ it "Should be able to generate events via the Systems Events" do
110
+ expect_execute_osascript(/tell application "System Events"; tell process #{quoted_name}; quit; end tell; end tell/)
111
+ subject.system_event!("quit")
112
+ end
113
+
114
+ it "Should be able to generate events via the Systems Events (with activate)" do
115
+ expect_activate
116
+ expect_system_event!("quit")
117
+ subject.system_event("quit")
118
+ end
119
+ end
120
+
121
+ context "Check whether things exist or not" do
122
+
123
+ it "Should be able to check whether a location exists" do
124
+ expect_execute_osascript(/exists button 1/).and_return("true\n")
125
+ subject.exists?(at.button(1)).should be_true
126
+ end
127
+
128
+ it "Should be able to check whether a location does not exists" do
129
+ expect_execute_osascript(/not exists window 1/).and_return("true\n")
130
+ subject.not_exists?(at.window(1)).should be_true
131
+ end
132
+ end
133
+
134
+ context "Waiting and doing until elements exist or not" do
135
+
136
+ it "Should be able to wait for only one location to exist" do
137
+ expect_exists?(at.button(1)).and_return(false, false, true)
138
+ subject.wait_until_exists!(at.button(1)).should == at.button(1)
139
+ end
140
+
141
+ it "Should be able to wait for only one location to exist (with activate)" do
142
+ expect_activate
143
+ expect_exists?(at.button(1)).and_return(false, false, true)
144
+ subject.wait_until_exists(at.button(1)).should == at.button(1)
145
+ end
146
+
147
+ it "Should be able to wait until multiple locations exists and return the one that happened" do
148
+ expect_exists?(at.button(1)).and_return(false, false, false)
149
+ expect_exists?(at.sheet(5)).and_return(false, false, true)
150
+ subject.wait_until_exists!(at.button(1), at.sheet(5)).should == at.sheet(5)
151
+ end
152
+
153
+ it "Should be able to wait until multiple locations exists and return the one that happened (with activate)" do
154
+ expect_activate
155
+ expect_exists?(at.button(1)).and_return(false, false)
156
+ expect_exists?(at.sheet(5)).and_return(false, true)
157
+ subject.wait_until_exists(at.button(1), at.sheet(5)).should == at.sheet(5)
158
+ end
159
+
160
+ it "Should be able to wait for one location to NOT exist" do
161
+ expect_not_exists?(at.button(1)).and_return(false, false, true)
162
+ subject.wait_until_not_exists!(at.button(1)).should == at.button(1)
163
+ end
164
+
165
+ it "Should be able to wait for one location to NOT exist (with activate)" do
166
+ expect_activate
167
+ expect_not_exists?(at.button(4)).and_return(false, true)
168
+ subject.wait_until_not_exists(at.button(4)).should == at.button(4)
169
+ end
170
+
171
+ it "Should be able to loop over some script until something happens" do
172
+ Timeout.should_receive(:timeout).with(5).and_yield
173
+ expect_execute_osascript.and_return("false", "false", "true")
174
+ expect_activate.twice
175
+
176
+
177
+ subject.until_exists!(at.window(1)) {
178
+ subject.activate
179
+ }
180
+ end
181
+
182
+ it "Should print a proper error message when it times out while waiting for something" do
183
+ Timeout.should_receive(:timeout).with(5).and_raise(Timeout::Error.new)
184
+ lambda { subject.until_exists!(at.window(1)) }.should raise_error(Osaka::TimeoutError, "Timed out while waiting for: [window 1]")
185
+ end
186
+ end
187
+
188
+ context "Short convenient methods for different actions" do
189
+
190
+ it "Has a short-cut method for quitting" do
191
+ expect_keystroke("q", :command)
192
+ subject.quit
193
+ end
194
+
195
+ it "Should print an Warning message with the ScriptRunner returns text when doing activate" do
196
+ expect_execute_and_warning_for("activate")
197
+ subject.activate
198
+ end
199
+
200
+ it "Should be able to launch and deal with the warning" do
201
+ expect_execute_and_warning_for("launch")
202
+ subject.launch
203
+ end
204
+ end
205
+
206
+
207
+
208
+ context "Can send keystrokes to the application" do
209
+
210
+ it "Should be able to generate keystroke events" do
211
+ expect_execute_osascript(/keystroke "p"/).and_return("")
212
+ subject.keystroke!("p")
213
+ end
214
+
215
+ it "Should be able to generate return keystroke event" do
216
+ expect_execute_osascript(/keystroke return/).and_return("")
217
+ subject.keystroke!(:return)
218
+ end
219
+
220
+ it "Prints a warning when keystroke results in some outputShould be able to generate keystroke events" do
221
+ expect_execute_and_warning_for("keystroke")
222
+ subject.keystroke!("p")
223
+ end
224
+
225
+ it "Should be able to keystroke and activate" do
226
+ expect_activate
227
+ expect_focus
228
+ expect_keystroke!("a")
229
+ subject.keystroke("a")
230
+ end
231
+
232
+ it "Should be able to do keystrokes with command down" do
233
+ expect_execute_osascript(/keystroke "p" using {command down}/).and_return("")
234
+ subject.keystroke!("p", :command)
235
+ end
236
+
237
+ it "Should be able to do keystrokes with option and command down" do
238
+ expect_execute_osascript(/keystroke "p" using {option down, command down}/).and_return("")
239
+ subject.keystroke!("p", [ :option, :command ])
240
+ end
241
+
242
+ it "Should be able to do a keystroke and wait until something happen in one easy line" do
243
+ expect_execute_osascript(/keystroke "p"/).and_return("")
244
+ expect_execute_osascript(/exists window 1/).and_return("true")
245
+ subject.keystroke!("p", []).wait_until_exists!(at.window(1))
246
+ end
247
+
248
+ it "Should be able to keystroke_and_wait_until_exists and activate" do
249
+ expect_activate
250
+ expect_focus
251
+ expect_execute_osascript(/keystroke "p"/).and_return("")
252
+ expect_execute_osascript(/exists window 1/).and_return("true")
253
+ subject.keystroke("p").wait_until_exists!(at.window(1))
254
+ end
255
+
256
+ end
257
+
258
+ context "Can send mouse clicks to the application" do
259
+
260
+ it "Should be able to do clicks" do
261
+ expect_execute_osascript(/click menu button "PDF"/).and_return("")
262
+ subject.click!(at.menu_button("PDF"))
263
+ end
264
+
265
+ it "Should be able to do click and activate" do
266
+ expect_activate
267
+ expect_click!("button")
268
+ subject.click("button")
269
+ end
270
+
271
+ it "Should be able to do clicks and wait until something happened in one easy line" do
272
+ expect_execute_osascript(/click/).and_return("")
273
+ expect_execute_osascript(/exists window 1/).and_return("true")
274
+ subject.click!("button").wait_until_exists!(at.window(1))
275
+ end
276
+
277
+ it "Should be able to click_and_wait_until_exists and activate" do
278
+ expect_activate
279
+ expect_execute_osascript(/click/).and_return("")
280
+ expect_execute_osascript(/exists window 1/).and_return("true")
281
+ subject.click("button").wait_until_exists!(at.window(1))
282
+ end
283
+
284
+ it "Should be able to click on menu bar items" do
285
+ expect_activate
286
+ expect_click!(at.menu_item("Hey").menu(1).menu_bar_item("File").menu_bar(1))
287
+ subject.click_menu_bar(at.menu_item("Hey"), "File")
288
+ end
289
+
290
+ end
291
+
292
+ context "Control should be able to set and get different application values" do
293
+
294
+ it "Should be able to set a value to an element" do
295
+ expect_system_event!(/set value of window 1 to "newvalue"/).and_return("")
296
+ subject.set!("value", at.window(1), "newvalue")
297
+ end
298
+
299
+ it "Prints a warning when setting and element and output is received" do
300
+ expect_execute_and_warning_for("set")
301
+ subject.set!("value", at.window(1), "newvalue")
302
+ end
303
+
304
+ it "Should be able to set to boolean values" do
305
+ expect_system_event!(/set value of window 1 to true/).and_return("")
306
+ subject.set!("value", at.window(1), true)
307
+ end
308
+
309
+ it "Should be able to get a value from an element" do
310
+ expect_system_event!(/get value of window 1/).and_return("1\n")
311
+ subject.get!("value", at.window(1)).should == "1"
312
+ end
313
+
314
+ it "Should use the locally stored window when that one is set." do
315
+ subject.set_current_window("1")
316
+ expect_system_event!(/get value of window \"1\"/).and_return("1\n")
317
+ subject.get!("value").should == "1"
318
+ end
319
+
320
+ it "Should combine the location and the window" do
321
+ subject.set_current_window("1")
322
+ expect_system_event!(/get value of dialog 2 of window "1"/).and_return("1\n")
323
+ subject.get!("value", at.dialog(2)).should == "1"
324
+ end
325
+
326
+ it "Should be able to get values from the application itself" do
327
+ expect_system_event!("get value").and_return("1\n")
328
+ subject.get_app!("value").should == "1"
329
+ end
330
+
331
+ it "Should be able to set a value and activate" do
332
+ expect_activate
333
+ expect_set!("value", at.window(1), "newvalue")
334
+ subject.set("value", at.window(1), "newvalue")
335
+ end
336
+
337
+ it "Should be able to get an empty array when requesting for the window list and there are none" do
338
+ expect_get_app!("windows").and_return("\n")
339
+ subject.window_list.should == []
340
+ end
341
+
342
+ it "Should be able get an array with one window name when there is exactly one window" do
343
+ expect_get_app!("windows").and_return("window one of application process process\n")
344
+ subject.window_list.should == ["one"]
345
+ end
346
+
347
+ end
348
+
349
+ describe "Dealing with base locations and window lists" do
350
+
351
+ it "Should be possible to pass a base location in the creation" do
352
+ subject = Osaka::RemoteControl.new("Application", at.window("Window"))
353
+ subject.base_location.should == at.window("Window")
354
+ end
355
+
356
+ it "Should be able to get an array of multiple window names" do
357
+ expect_get_app!("windows").and_return("window one of application process process, window two of application process process\n")
358
+ subject.window_list.should == ["one", "two"]
359
+ end
360
+
361
+ it "Should be able to focus the currently active window" do
362
+ subject.base_location = at.sheet(1).window("boo")
363
+ expect_system_event!("set value of attribute \"AXMain\" of window \"boo\" to true")
364
+ subject.focus!
365
+ end
366
+
367
+ it "Should initialize the current window when it is not focused yet" do
368
+ expect_window_list.and_return(["1"])
369
+ expect_focus!
370
+ subject.focus
371
+ subject.current_window_name.should == "1"
372
+ end
373
+
374
+ it "Should be able to extract the current window name also when the base location has more than just a window " do
375
+ subject.base_location = at.sheet(1).window("Window")
376
+ subject.current_window_name.should == "Window"
377
+ end
378
+
379
+ it "Shouldn't initialize current window when it is already set" do
380
+ subject.set_current_window("1")
381
+ expect_not_exists?(at.window("1")).and_return(false)
382
+ expect_focus!
383
+
384
+ subject.focus
385
+ subject.base_location.should == at.window("1")
386
+ end
387
+
388
+ it "Should re-initialize the current window when it doesn't exist anymore" do
389
+ subject.set_current_window("1")
390
+ expect_not_exists?(at.window("1")).and_return(true)
391
+ expect_window_list.and_return(["2"])
392
+ expect_focus!
393
+
394
+ subject.focus
395
+ subject.current_window_name.should == "2"
396
+ end
397
+
398
+ it "Should focus the current window when it doesn't have focus" do
399
+ subject.set_current_window("1")
400
+ expect_not_exists?(at.window("1")).and_return(false)
401
+ expect_focus!
402
+ subject.focus
403
+ end
404
+
405
+ it "Shouldn't focus when there is no window set at all" do
406
+ expect_window_list.and_return([""])
407
+ subject.focus
408
+ end
409
+
410
+ end
411
+ end
@@ -32,6 +32,17 @@ describe "Osaka::ScriptRunner" do
32
32
  Osaka::ScriptRunner::disable_debug_prints
33
33
  end
34
34
 
35
+ it "Should be able to generate a script of the run for later debugging purposes" do
36
+ subject.should_receive(:do_system).and_return("Blah blah blah")
37
+ file = mock("Mocked output file")
38
+ File.should_receive(:open).with("output_script", File::WRONLY|File::APPEND|File::CREAT, 0755).and_yield(file)
39
+ file.should_receive(:puts).with("osascript -e \"random number\"")
40
+ Osaka::ScriptRunner.enable_debug_prints(:script, "output_script")
41
+ subject.execute("random number")
42
+ Osaka::ScriptRunner::disable_debug_prints
43
+ end
44
+
45
+
35
46
  it "Should not print any debugging information by default " do
36
47
  subject.should_receive(:do_system).and_return("")
37
48
  subject.should_not_receive(:puts)
@@ -57,4 +68,5 @@ describe "Osaka::ScriptRunner" do
57
68
  subject.should_receive(:do_system).with('osascript script.scpt a b c').and_return(true)
58
69
  subject.execute_file("script.scpt", "a b c")
59
70
  end
71
+
60
72
  end
@@ -3,11 +3,11 @@ require 'osaka'
3
3
 
4
4
  describe "TextEdit" do
5
5
 
6
- include(*Osaka::ApplicationWrapperExpectations)
6
+ include(*Osaka::OsakaExpectations)
7
7
 
8
8
  subject { Osaka::TextEdit.new }
9
9
 
10
- let(:wrapper) { subject.wrapper = double("Osaka::ApplicationWrapper") }
10
+ let(:control) { subject.control = mock("RemoteControl") }
11
11
 
12
12
  it "Should be able to type some text" do
13
13
  expect_keystroke('Hello World')