osaka 0.3.2 → 0.4.0

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.
@@ -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')