osaka 0.4.8 → 0.4.10
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.
- checksums.yaml +7 -0
- data/Gemfile +7 -0
- data/README.rdoc +1 -1
- data/Rakefile +12 -2
- data/lib/osaka.rb +6 -0
- data/lib/osaka/calculator.rb +1 -1
- data/lib/osaka/commandrunner.rb +17 -0
- data/lib/osaka/defaultssystem.rb +28 -0
- data/lib/osaka/keynote.rb +8 -6
- data/lib/osaka/keynoteflow.rb +10 -2
- data/lib/osaka/launchservices.rb +29 -0
- data/lib/osaka/location.rb +1 -1
- data/lib/osaka/mailmergeflow.rb +1 -1
- data/lib/osaka/numbers.rb +1 -1
- data/lib/osaka/osakaexpectations.rb +65 -61
- data/lib/osaka/pages.rb +35 -26
- data/lib/osaka/preview.rb +1 -1
- data/lib/osaka/remotecontrol.rb +57 -47
- data/lib/osaka/scriptrunner.rb +2 -11
- data/lib/osaka/textedit.rb +1 -1
- data/lib/osaka/typicalapplication.rb +10 -4
- data/lib/osaka/typicalfinderdialog.rb +1 -1
- data/lib/osaka/typicalopendialog.rb +22 -18
- data/lib/osaka/typicalprintdialog.rb +1 -1
- data/lib/osaka/typicalsavedialog.rb +1 -1
- data/lib/osaka/version.rb +1 -1
- data/{osaka.gemfile → osaka.gemspec} +0 -0
- data/spec/assets/document.pdf +0 -0
- data/spec/calculator_spec.rb +5 -5
- data/spec/defaultssystem_spec.rb +30 -0
- data/spec/integration_calculator_spec.rb +7 -7
- data/spec/integration_keynote_spec.rb +24 -11
- data/spec/integration_numbers_spec.rb +2 -2
- data/spec/integration_pages_numbers_mail_merge_spec.rb +9 -9
- data/spec/integration_preview_spec.rb +16 -0
- data/spec/integration_textedit_spec.rb +5 -5
- data/spec/keynote_flows_spec.rb +52 -31
- data/spec/keynote_spec.rb +24 -14
- data/spec/launchservices_spec.rb +63 -0
- data/spec/location_spec.rb +13 -13
- data/spec/mailmergeflow_spec.rb +13 -13
- data/spec/numbers_spec.rb +10 -10
- data/spec/osakaexpectations_spec.rb +3 -3
- data/spec/pages_spec.rb +80 -61
- data/spec/preview_spec.rb +5 -5
- data/spec/remotecontrol_spec.rb +65 -43
- data/spec/scriptrunner_spec.rb +22 -22
- data/spec/textedit_spec.rb +3 -3
- data/spec/typicalapplication_spec.rb +119 -108
- data/spec/typicalfinderdialog_spec.rb +2 -2
- data/spec/typicalopendialog_spec.rb +41 -35
- data/spec/typicalprintdialog_spec.rb +5 -5
- data/spec/typicalsavedialog_spec.rb +10 -10
- metadata +51 -47
data/spec/preview_spec.rb
CHANGED
@@ -6,22 +6,22 @@ describe "Preview application for reading PDFs" do
|
|
6
6
|
include(*Osaka::OsakaExpectations)
|
7
7
|
|
8
8
|
subject { Osaka::Preview.new }
|
9
|
-
let(:control) { subject.control =
|
9
|
+
let(:control) { subject.control = double("RemoteControl", :mac_version => :mountain_lion)}
|
10
10
|
|
11
11
|
it "Can get the text context of a PDF document" do
|
12
12
|
expect_get!("value", at.static_text(1).scroll_area(1).splitter_group(1)).and_return("Blah")
|
13
|
-
subject.pdf_content.
|
13
|
+
expect(subject.pdf_content).to eq "Blah"
|
14
14
|
end
|
15
15
|
|
16
16
|
it "Can open a PDF file via the menu instead of the AppleScript 'open' as that one is buggy" do
|
17
17
|
|
18
18
|
expect_click_menu_bar(at.menu_item("Open…"), "File")
|
19
19
|
expect_wait_until_exists(at.window("Open"))
|
20
|
-
subject.
|
21
|
-
subject.
|
20
|
+
expect(subject).to receive(:do_and_wait_for_new_window).and_yield.and_return("window name")
|
21
|
+
expect(subject).to receive(:select_file_from_open_dialog).with("dir/filename", at.window("Open"))
|
22
22
|
expect_set_current_window("window name")
|
23
23
|
|
24
24
|
subject.open("dir/filename")
|
25
25
|
end
|
26
26
|
|
27
|
-
end
|
27
|
+
end
|
data/spec/remotecontrol_spec.rb
CHANGED
@@ -18,14 +18,13 @@ describe "Osaka::RemoteControl" do
|
|
18
18
|
Osaka::ScriptRunner.disable_debug_prints
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
21
|
def expect_execute_and_warning_for(action)
|
23
22
|
expect_execute_osascript.and_return("An Error")
|
24
|
-
subject.
|
23
|
+
expect(subject).to receive(:puts).with(/#{action}/)
|
25
24
|
end
|
26
25
|
|
27
26
|
it "Should be able to print warning messages" do
|
28
|
-
subject.
|
27
|
+
expect(subject).to receive(:puts).with("Osaka WARNING while doing ThisAction: Message")
|
29
28
|
subject.print_warning("ThisAction", "Message")
|
30
29
|
end
|
31
30
|
|
@@ -33,28 +32,28 @@ describe "Osaka::RemoteControl" do
|
|
33
32
|
|
34
33
|
it "Should be possible to check whether an application is still running" do
|
35
34
|
expect_execute_osascript("tell application \"System Events\"; (name of processes) contains \"#{name}\"; end tell").and_return("false")
|
36
|
-
subject.running
|
35
|
+
expect(subject.running?).to be false
|
37
36
|
end
|
38
37
|
|
39
38
|
it "Can get the OS version (lion)" do
|
40
39
|
expect_execute_osascript("system version of (system info)").and_return("10.7.4\n")
|
41
|
-
subject.mac_version.
|
42
|
-
subject.mac_version_string.
|
40
|
+
expect(subject.mac_version).to eq :lion
|
41
|
+
expect(subject.mac_version_string).to eq "10.7.4"
|
43
42
|
end
|
44
43
|
|
45
44
|
it "Can get the OS version (mountain lion)" do
|
46
45
|
expect_execute_osascript("system version of (system info)").and_return("10.8\n")
|
47
|
-
subject.mac_version.
|
46
|
+
expect(subject.mac_version).to eq :mountain_lion
|
48
47
|
end
|
49
48
|
|
50
49
|
it "Can get the OS version (snow leopard)" do
|
51
50
|
expect_execute_osascript("system version of (system info)").and_return("10.6\n")
|
52
|
-
subject.mac_version.
|
51
|
+
expect(subject.mac_version).to eq :snow_leopard
|
53
52
|
end
|
54
53
|
|
55
54
|
it "Can get the OS version (snow leopard)" do
|
56
55
|
expect_execute_osascript("system version of (system info)").and_return("1\n")
|
57
|
-
subject.mac_version.
|
56
|
+
expect(subject.mac_version).to eq :other
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
@@ -63,21 +62,21 @@ describe "Osaka::RemoteControl" do
|
|
63
62
|
it "Should be able to clone controls" do
|
64
63
|
subject.set_current_window "Window"
|
65
64
|
new_control = subject.clone
|
66
|
-
new_control.
|
67
|
-
new_control.
|
65
|
+
expect(new_control).to eq subject
|
66
|
+
expect(new_control).not_to be subject
|
68
67
|
end
|
69
68
|
|
70
69
|
it "Should be having different current window instances when cloning" do
|
71
70
|
subject.set_current_window "Window"
|
72
71
|
new_control = subject.clone
|
73
72
|
new_control.set_current_window "Not the same"
|
74
|
-
subject.current_window_name.
|
73
|
+
expect(subject.current_window_name).not_to be new_control.current_window_name
|
75
74
|
|
76
75
|
end
|
77
76
|
|
78
77
|
it "Should be able to compare objects using names" do
|
79
|
-
subject.
|
80
|
-
subject.
|
78
|
+
expect(subject).to eq Osaka::RemoteControl.new(name)
|
79
|
+
expect(subject).not_to eq Osaka::RemoteControl.new("otherName")
|
81
80
|
end
|
82
81
|
|
83
82
|
it "Should be able to compare objects using window" do
|
@@ -87,8 +86,8 @@ describe "Osaka::RemoteControl" do
|
|
87
86
|
subject.set_current_window("Window")
|
88
87
|
unequal_object.set_current_window "Another Window"
|
89
88
|
|
90
|
-
subject.
|
91
|
-
subject.
|
89
|
+
expect(subject).to eq equal_object
|
90
|
+
expect(subject).not_to eq unequal_object
|
92
91
|
end
|
93
92
|
end
|
94
93
|
|
@@ -122,12 +121,12 @@ describe "Osaka::RemoteControl" do
|
|
122
121
|
|
123
122
|
it "Should be able to check whether a location exists" do
|
124
123
|
expect_execute_osascript(/exists button 1/).and_return("true\n")
|
125
|
-
subject.exists?(at.button(1)).
|
124
|
+
expect(subject.exists?(at.button(1))).to be true
|
126
125
|
end
|
127
126
|
|
128
127
|
it "Should be able to check whether a location does not exists" do
|
129
128
|
expect_execute_osascript(/not exists window 1/).and_return("true\n")
|
130
|
-
subject.not_exists?(at.window(1)).
|
129
|
+
expect(subject.not_exists?(at.window(1))).to be true
|
131
130
|
end
|
132
131
|
end
|
133
132
|
|
@@ -135,41 +134,41 @@ describe "Osaka::RemoteControl" do
|
|
135
134
|
|
136
135
|
it "Should be able to wait for only one location to exist" do
|
137
136
|
expect_exists?(at.button(1)).and_return(false, false, true)
|
138
|
-
subject.wait_until_exists!(at.button(1)).
|
137
|
+
expect(subject.wait_until_exists!(at.button(1))).to eq at.button(1)
|
139
138
|
end
|
140
139
|
|
141
140
|
it "Should be able to wait for only one location to exist (with activate)" do
|
142
141
|
expect_activate
|
143
142
|
expect_exists?(at.button(1)).and_return(false, false, true)
|
144
|
-
subject.wait_until_exists(at.button(1)).
|
143
|
+
expect(subject.wait_until_exists(at.button(1))).to eq at.button(1)
|
145
144
|
end
|
146
145
|
|
147
146
|
it "Should be able to wait until multiple locations exists and return the one that happened" do
|
148
147
|
expect_exists?(at.button(1)).and_return(false, false, false)
|
149
148
|
expect_exists?(at.sheet(5)).and_return(false, false, true)
|
150
|
-
subject.wait_until_exists!(at.button(1), at.sheet(5)).
|
149
|
+
expect(subject.wait_until_exists!(at.button(1), at.sheet(5))).to eq at.sheet(5)
|
151
150
|
end
|
152
151
|
|
153
152
|
it "Should be able to wait until multiple locations exists and return the one that happened (with activate)" do
|
154
153
|
expect_activate
|
155
154
|
expect_exists?(at.button(1)).and_return(false, false)
|
156
155
|
expect_exists?(at.sheet(5)).and_return(false, true)
|
157
|
-
subject.wait_until_exists(at.button(1), at.sheet(5)).
|
156
|
+
expect(subject.wait_until_exists(at.button(1), at.sheet(5))).to eq at.sheet(5)
|
158
157
|
end
|
159
158
|
|
160
159
|
it "Should be able to wait for one location to NOT exist" do
|
161
160
|
expect_not_exists?(at.button(1)).and_return(false, false, true)
|
162
|
-
subject.wait_until_not_exists!(at.button(1)).
|
161
|
+
expect(subject.wait_until_not_exists!(at.button(1))).to eq at.button(1)
|
163
162
|
end
|
164
163
|
|
165
164
|
it "Should be able to wait for one location to NOT exist (with activate)" do
|
166
165
|
expect_activate
|
167
166
|
expect_not_exists?(at.button(4)).and_return(false, true)
|
168
|
-
subject.wait_until_not_exists(at.button(4)).
|
167
|
+
expect(subject.wait_until_not_exists(at.button(4))).to eq at.button(4)
|
169
168
|
end
|
170
169
|
|
171
170
|
it "Should be able to loop over some script until something happens" do
|
172
|
-
Timeout.
|
171
|
+
expect(Timeout).to receive(:timeout).with(10).and_yield
|
173
172
|
expect_execute_osascript.and_return("false", "false", "true")
|
174
173
|
expect_activate.twice
|
175
174
|
|
@@ -180,8 +179,13 @@ describe "Osaka::RemoteControl" do
|
|
180
179
|
end
|
181
180
|
|
182
181
|
it "Should print a proper error message when it times out while waiting for something" do
|
183
|
-
Timeout.
|
184
|
-
expect { subject.until_exists!(at.window(1)) }.to raise_error(Osaka::TimeoutError, "Timed out while waiting for:
|
182
|
+
expect(Timeout).to receive(:timeout).with(10).and_raise(Timeout::Error.new)
|
183
|
+
expect { subject.until_exists!(at.window(1)) }.to raise_error(Osaka::TimeoutError, "Timed out while waiting for: window 1")
|
184
|
+
end
|
185
|
+
|
186
|
+
it "Should print a proper error message when it times out while waiting for more than one thing" do
|
187
|
+
expect(Timeout).to receive(:timeout).with(10).and_raise(Timeout::Error.new)
|
188
|
+
expect { subject.until_exists!(at.window(1), at.button(2)) }.to raise_error(Osaka::TimeoutError, "Timed out while waiting for: window 1, button 2")
|
185
189
|
end
|
186
190
|
end
|
187
191
|
|
@@ -290,7 +294,7 @@ describe "Osaka::RemoteControl" do
|
|
290
294
|
end
|
291
295
|
|
292
296
|
context "Control should be able to set and get different application values" do
|
293
|
-
|
297
|
+
|
294
298
|
it "Should be able to set a value to an element" do
|
295
299
|
expect_system_event!(/set value of window 1 to "newvalue"/).and_return("")
|
296
300
|
subject.set!("value", at.window(1), "newvalue")
|
@@ -308,24 +312,24 @@ describe "Osaka::RemoteControl" do
|
|
308
312
|
|
309
313
|
it "Should be able to get a value from an element" do
|
310
314
|
expect_system_event!(/get value of window 1/).and_return("1\n")
|
311
|
-
subject.get!("value", at.window(1)).
|
315
|
+
expect(subject.get!("value", at.window(1))).to eq "1"
|
312
316
|
end
|
313
317
|
|
314
318
|
it "Should use the locally stored window when that one is set." do
|
315
319
|
subject.set_current_window("1")
|
316
320
|
expect_system_event!(/get value of window \"1\"/).and_return("1\n")
|
317
|
-
subject.get!("value").
|
321
|
+
expect(subject.get!("value")).to eq "1"
|
318
322
|
end
|
319
323
|
|
320
324
|
it "Should combine the location and the window" do
|
321
325
|
subject.set_current_window("1")
|
322
326
|
expect_system_event!(/get value of dialog 2 of window "1"/).and_return("1\n")
|
323
|
-
subject.get!("value", at.dialog(2)).
|
327
|
+
expect(subject.get!("value", at.dialog(2))).to eq "1"
|
324
328
|
end
|
325
329
|
|
326
330
|
it "Should be able to get values from the application itself" do
|
327
331
|
expect_system_event!("get value").and_return("1\n")
|
328
|
-
subject.get_app!("value").
|
332
|
+
expect(subject.get_app!("value")).to eq "1"
|
329
333
|
end
|
330
334
|
|
331
335
|
it "Should be able to set a value and activate" do
|
@@ -336,22 +340,40 @@ describe "Osaka::RemoteControl" do
|
|
336
340
|
|
337
341
|
it "Should be able to get an empty array when requesting for the window list and there are none" do
|
338
342
|
expect_get_app!("windows").and_return("\n")
|
339
|
-
subject.window_list.
|
343
|
+
expect(subject.window_list).to eq []
|
340
344
|
end
|
341
345
|
|
342
346
|
it "Should be able get an array with one window name when there is exactly one window" do
|
343
347
|
expect_get_app!("windows").and_return("window one of application process process\n")
|
344
|
-
subject.window_list.
|
348
|
+
expect(subject.window_list).to eq ["one"]
|
349
|
+
end
|
350
|
+
|
351
|
+
it "Should be able to get a list of standard windows which is empty" do
|
352
|
+
expect(subject).to receive(:window_list).and_return([])
|
353
|
+
subject.standard_window_list
|
354
|
+
end
|
355
|
+
|
356
|
+
it "Should be able to get a list of all the standard windows when there are only standard windows " do
|
357
|
+
expect(subject).to receive(:window_list).and_return(["window 1"])
|
358
|
+
expect_get!("subrole", at.window("window 1")).and_return("AXStandardWindow")
|
359
|
+
expect(subject.standard_window_list).to eq ["window 1"]
|
360
|
+
end
|
361
|
+
|
362
|
+
it "Should be able to get a list of all the standard windows excluding the floating ones" do
|
363
|
+
expect(subject).to receive(:window_list).and_return(["window", "float"])
|
364
|
+
expect_get!("subrole", at.window("window")).and_return("AXStandardWindow")
|
365
|
+
expect_get!("subrole", at.window("float")).and_return("AXFloatingWindow")
|
366
|
+
expect(subject.standard_window_list).to eq ["window"]
|
345
367
|
end
|
346
368
|
|
347
369
|
it "Should be able to get the attributes of a window and parse the result" do
|
348
370
|
expect_get!("attributes", at.window(1)).and_return("attribute AXRole of window 1 of application process ApplicationName, attribute AXRoleDescription of window 1 of application process ApplicationName, attribute AXSubrole of window 1 of application process ApplicationName")
|
349
|
-
subject.attributes(at.window(1)).
|
371
|
+
expect(subject.attributes(at.window(1))).to eq ["AXRole", "AXRoleDescription", "AXSubrole"]
|
350
372
|
end
|
351
373
|
|
352
374
|
it "Should be able to get the attributes of the application too" do
|
353
375
|
expect_get!("attributes", at.window(1)).and_return("attribute AXRole of application process ApplicationName, attribute AXRoleDescription of application process ApplicationName")
|
354
|
-
subject.attributes(at.window(1)).
|
376
|
+
expect(subject.attributes(at.window(1))).to eq ["AXRole", "AXRoleDescription"]
|
355
377
|
end
|
356
378
|
|
357
379
|
end
|
@@ -360,12 +382,12 @@ describe "Osaka::RemoteControl" do
|
|
360
382
|
|
361
383
|
it "Should be possible to pass a base location in the creation" do
|
362
384
|
subject = Osaka::RemoteControl.new("Application", at.window("Window"))
|
363
|
-
subject.base_location.
|
385
|
+
expect(subject.base_location).to eq at.window("Window")
|
364
386
|
end
|
365
387
|
|
366
388
|
it "Should be able to get an array of multiple window names" do
|
367
389
|
expect_get_app!("windows").and_return("window one of application process process, window two of application process process\n")
|
368
|
-
subject.window_list.
|
390
|
+
expect(subject.window_list).to eq ["one", "two"]
|
369
391
|
end
|
370
392
|
|
371
393
|
it "Should be able to focus the currently active window" do
|
@@ -378,12 +400,12 @@ describe "Osaka::RemoteControl" do
|
|
378
400
|
expect_window_list.and_return(["1"])
|
379
401
|
expect_focus!
|
380
402
|
subject.focus
|
381
|
-
subject.current_window_name.
|
403
|
+
expect(subject.current_window_name).to eq "1"
|
382
404
|
end
|
383
405
|
|
384
406
|
it "Should be able to extract the current window name also when the base location has more than just a window " do
|
385
407
|
subject.base_location = at.sheet(1).window("Window")
|
386
|
-
subject.current_window_name.
|
408
|
+
expect(subject.current_window_name).to eq "Window"
|
387
409
|
end
|
388
410
|
|
389
411
|
it "Shouldn't initialize current window when it is already set" do
|
@@ -392,7 +414,7 @@ describe "Osaka::RemoteControl" do
|
|
392
414
|
expect_focus!
|
393
415
|
|
394
416
|
subject.focus
|
395
|
-
subject.base_location.
|
417
|
+
expect(subject.base_location).to eq at.window("1")
|
396
418
|
end
|
397
419
|
|
398
420
|
it "Should re-initialize the current window when it doesn't exist anymore" do
|
@@ -402,7 +424,7 @@ describe "Osaka::RemoteControl" do
|
|
402
424
|
expect_focus!
|
403
425
|
|
404
426
|
subject.focus
|
405
|
-
subject.current_window_name.
|
427
|
+
expect(subject.current_window_name).to eq "2"
|
406
428
|
end
|
407
429
|
|
408
430
|
it "Should focus the current window when it doesn't have focus" do
|
@@ -418,4 +440,4 @@ describe "Osaka::RemoteControl" do
|
|
418
440
|
end
|
419
441
|
|
420
442
|
end
|
421
|
-
end
|
443
|
+
end
|
data/spec/scriptrunner_spec.rb
CHANGED
@@ -5,73 +5,73 @@ describe "Osaka::ScriptRunner" do
|
|
5
5
|
subject { Osaka::ScriptRunner }
|
6
6
|
|
7
7
|
it "Should be able to run single-line text as osascript" do
|
8
|
-
|
9
|
-
subject.execute("random number").
|
8
|
+
expect(Osaka::CommandRunner).to receive(:run).with('osascript -e "random number"').and_return("")
|
9
|
+
expect(subject.execute("random number")).to eq ""
|
10
10
|
end
|
11
11
|
|
12
12
|
it "Should escape quotes when passing text" do
|
13
|
-
|
13
|
+
expect(Osaka::CommandRunner).to receive(:run).with('osascript -e "say \\"hello\\""').and_return("")
|
14
14
|
subject.execute('say "hello"')
|
15
15
|
end
|
16
16
|
|
17
17
|
it "Should be able to run on debug printing" do
|
18
|
-
|
19
|
-
subject.
|
20
|
-
subject.
|
18
|
+
expect(Osaka::CommandRunner).to receive(:run).and_return("Blah blah blah")
|
19
|
+
expect(subject).to receive(:puts).with('Executing: osascript -e "random number"')
|
20
|
+
expect(subject).to receive(:puts).with('Output was: Blah blah blah')
|
21
21
|
Osaka::ScriptRunner::enable_debug_prints
|
22
22
|
subject.execute("random number")
|
23
23
|
Osaka::ScriptRunner::disable_debug_prints
|
24
24
|
end
|
25
25
|
|
26
26
|
it "Should be able to run on debug printing with HTML tags" do
|
27
|
-
|
28
|
-
subject.
|
29
|
-
subject.
|
27
|
+
expect(Osaka::CommandRunner).to receive(:run).and_return("Blah blah blah")
|
28
|
+
expect(subject).to receive(:puts).with('random number<br>')
|
29
|
+
expect(subject).to receive(:puts).with('Output: <b>Blah blah blah</b><br>')
|
30
30
|
Osaka::ScriptRunner::enable_debug_prints(:short_html)
|
31
31
|
subject.execute("random number")
|
32
32
|
Osaka::ScriptRunner::disable_debug_prints
|
33
33
|
end
|
34
34
|
|
35
35
|
it "Should be able to generate a script of the run for later debugging purposes" do
|
36
|
-
|
37
|
-
file =
|
38
|
-
File.
|
39
|
-
file.
|
36
|
+
expect(Osaka::CommandRunner).to receive(:run).and_return("Blah blah blah")
|
37
|
+
file = double("Mocked output file")
|
38
|
+
expect(File).to receive(:open).with("output_script", File::WRONLY|File::APPEND|File::CREAT, 0755).and_yield(file)
|
39
|
+
expect(file).to receive(:puts).with("osascript -e \"random number\"")
|
40
40
|
Osaka::ScriptRunner.enable_debug_prints(:script, "output_script")
|
41
41
|
subject.execute("random number")
|
42
42
|
Osaka::ScriptRunner::disable_debug_prints
|
43
43
|
end
|
44
44
|
|
45
45
|
it "Should explain how to turn on the access for assistive devices when it is disabled... and exit" do
|
46
|
-
|
47
|
-
subject.
|
48
|
-
subject.
|
46
|
+
expect(Osaka::CommandRunner).to receive(:run).and_raise(Osaka::SystemCommandFailed.new ("execution error: System Events got an error: Access for assistive devices is disabled. (-25211)"))
|
47
|
+
expect(subject).to receive(:puts).with(/system preferences/)
|
48
|
+
expect(subject).to receive(:exit)
|
49
49
|
subject.execute("anything")
|
50
50
|
end
|
51
51
|
|
52
52
|
it "Should not print any debugging information by default " do
|
53
|
-
|
54
|
-
subject.
|
53
|
+
expect(Osaka::CommandRunner).to receive(:run).and_return("")
|
54
|
+
expect(subject).not_to receive :puts
|
55
55
|
subject.execute("random number")
|
56
56
|
end
|
57
57
|
|
58
58
|
it "Should be able to define multi-line statements using ; as a separator" do
|
59
|
-
|
59
|
+
expect(Osaka::CommandRunner).to receive(:run).with('osascript -e "tell application \\"Calculator\\"" -e "activate" -e "end tell"').and_return("")
|
60
60
|
subject.execute('tell application "Calculator"; activate; end tell')
|
61
61
|
end
|
62
62
|
|
63
63
|
it "Should raise an exception witha proper error message when the applescript fails" do
|
64
|
-
|
64
|
+
expect(Osaka::CommandRunner).to receive(:run).and_raise(Osaka::SystemCommandFailed.new("Message"))
|
65
65
|
expect {subject.execute("Fuck off!")}.to raise_error(Osaka::ScriptRunnerError, "Error received while executing: \"Fuck off!\" with message \"Message\"")
|
66
66
|
end
|
67
67
|
|
68
68
|
it "Should be able to execute an file containing applescript" do
|
69
|
-
|
69
|
+
expect(Osaka::CommandRunner).to receive(:run).with('osascript script.scpt').and_return(true)
|
70
70
|
subject.execute_file("script.scpt")
|
71
71
|
end
|
72
72
|
|
73
73
|
it "Should be able to pass parameters to an applescript" do
|
74
|
-
|
74
|
+
expect(Osaka::CommandRunner).to receive(:run).with('osascript script.scpt a b c').and_return(true)
|
75
75
|
subject.execute_file("script.scpt", "a b c")
|
76
76
|
end
|
77
77
|
|
data/spec/textedit_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe "TextEdit" do
|
|
7
7
|
|
8
8
|
subject { Osaka::TextEdit.new }
|
9
9
|
|
10
|
-
let(:control) { subject.control =
|
10
|
+
let(:control) { subject.control = double("RemoteControl") }
|
11
11
|
|
12
12
|
it "Should be able to type some text" do
|
13
13
|
expect_keystroke('Hello World')
|
@@ -16,7 +16,7 @@ describe "TextEdit" do
|
|
16
16
|
|
17
17
|
it "Should be able to get the text from the document" do
|
18
18
|
expect_get!("value", 'text area 1 of scroll area 1').and_return("Hello")
|
19
|
-
subject.text.
|
19
|
+
expect(subject.text).to eq "Hello"
|
20
20
|
end
|
21
21
|
|
22
|
-
end
|
22
|
+
end
|
@@ -4,110 +4,110 @@ require 'osaka'
|
|
4
4
|
describe "Osaka::TypicalApplication" do
|
5
5
|
|
6
6
|
include(*Osaka::OsakaExpectations)
|
7
|
-
|
7
|
+
|
8
8
|
subject { Osaka::TypicalApplication.new("ApplicationName") }
|
9
|
-
|
10
|
-
let(:control) { subject.control =
|
9
|
+
|
10
|
+
let(:control) { subject.control = double("RemoteControl", :name => "ApplicationName", :base_location => "base", :mac_version => :mountain_lion) }
|
11
11
|
|
12
12
|
before (:each) do
|
13
13
|
Osaka::ScriptRunner.enable_debug_prints
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
after (:each) do
|
17
17
|
Osaka::ScriptRunner.disable_debug_prints
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it "Should be able to do something and wait until a new window pops up" do
|
21
21
|
expect_window_list.and_return(["original window"], ["original window"], ["original window"], ["new window", "original window"])
|
22
22
|
expect_activate
|
23
23
|
code_block_called = false
|
24
|
-
subject.do_and_wait_for_new_window {
|
24
|
+
expect(subject.do_and_wait_for_new_window {
|
25
25
|
code_block_called = true
|
26
|
-
}.
|
27
|
-
code_block_called.
|
26
|
+
}).to eq "new window"
|
27
|
+
expect(code_block_called).to eq true
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
context "Cloning and copying" do
|
31
|
-
|
31
|
+
|
32
32
|
it "Should be able to clone TypicalApplications" do
|
33
33
|
expect_clone
|
34
|
-
subject.clone
|
34
|
+
subject.clone
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
it "Should be able to clone the typical applications and the remote controls will be different" do
|
38
38
|
subject.control.set_current_window "Original"
|
39
39
|
new_instance = subject.clone
|
40
40
|
new_instance.control.set_current_window "Clone"
|
41
|
-
subject.control.current_window_name.
|
41
|
+
expect(subject.control.current_window_name).to eq "Original"
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
context "Opening and new document" do
|
47
|
-
|
47
|
+
|
48
48
|
it "Should pass the right open string to the application osascript" do
|
49
49
|
filename = "filename.key"
|
50
50
|
expect_tell("open \"#{File.absolute_path(filename)}\"")
|
51
|
-
subject.
|
51
|
+
expect(subject).to receive(:do_and_wait_for_new_window).and_yield.and_return(filename)
|
52
52
|
expect_set_current_window(filename)
|
53
|
-
subject.open(filename)
|
53
|
+
subject.open(filename)
|
54
54
|
end
|
55
55
|
|
56
56
|
it "Should only get the basename of the filename when it sets the window title." do
|
57
57
|
filename = "/root/dirname/filename.key"
|
58
|
-
subject.
|
58
|
+
expect(subject).to receive(:do_and_wait_for_new_window).and_return("filename")
|
59
59
|
expect_set_current_window("filename")
|
60
|
-
subject.open(filename)
|
60
|
+
subject.open(filename)
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
it "Should be able to create a new document" do
|
64
|
-
subject.
|
64
|
+
expect(subject).to receive(:do_and_wait_for_new_window).and_yield.and_return("new_window")
|
65
65
|
expect_keystroke("n", :command)
|
66
66
|
expect_set_current_window("new_window")
|
67
67
|
expect_focus
|
68
68
|
subject.new_document
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
it "Should be able to easily create a document, put something, save it, and close it again" do
|
72
72
|
|
73
|
-
subject.
|
74
|
-
subject.
|
75
|
-
subject.
|
76
|
-
subject.
|
73
|
+
expect(subject).to receive(:new_document)
|
74
|
+
expect(subject).to receive(:method_call_from_code_block)
|
75
|
+
expect(subject).to receive(:save_as).with("filename")
|
76
|
+
expect(subject).to receive(:close)
|
77
77
|
|
78
78
|
subject.create_document("filename") { |doc|
|
79
79
|
doc.method_call_from_code_block
|
80
80
|
}
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
end
|
84
|
-
|
84
|
+
|
85
85
|
context "Quiting and closing and checking whether the app is still running" do
|
86
|
-
|
86
|
+
|
87
87
|
it "Should be able to quit" do
|
88
88
|
expect_running?.and_return(true)
|
89
89
|
expect_quit
|
90
90
|
subject.quit
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
it "Should be able to check if its running" do
|
94
94
|
expect_running?.and_return(true)
|
95
|
-
subject.running
|
95
|
+
expect(subject.running?).to be true
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
it "Won't quit when the application isn't running" do
|
99
99
|
expect_running?.and_return(false)
|
100
|
-
subject.quit(:dont_save)
|
100
|
+
subject.quit(:dont_save)
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
it "Should be able to quit without saving" do
|
104
104
|
expect_running?.and_return(true, true, false)
|
105
105
|
expect_quit
|
106
106
|
expect_exists?(at.sheet(1)).and_return(true)
|
107
107
|
expect_click!(at.button("Don’t Save").sheet(1))
|
108
|
-
subject.quit(:dont_save)
|
108
|
+
subject.quit(:dont_save)
|
109
109
|
end
|
110
|
-
|
110
|
+
|
111
111
|
it "Should be able to close" do
|
112
112
|
expect_keystroke("w", :command)
|
113
113
|
subject.close
|
@@ -115,120 +115,120 @@ describe "Osaka::TypicalApplication" do
|
|
115
115
|
|
116
116
|
it "Should be able to close and don't save" do
|
117
117
|
expect_keystroke("w", :command)
|
118
|
-
subject.
|
118
|
+
expect(subject).to receive(:wait_for_window_and_dialogs_to_close).with(:dont_save)
|
119
119
|
subject.close(:dont_save)
|
120
120
|
end
|
121
|
-
|
121
|
+
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
context "Save and duplicate documents" do
|
125
|
-
|
126
|
-
let(:save_dialog) {
|
127
|
-
let(:new_instance_control) {
|
128
|
-
|
125
|
+
|
126
|
+
let(:save_dialog) { double("Typical Save Dialog") }
|
127
|
+
let(:new_instance_control) { double("RemoteControl") }
|
128
|
+
|
129
129
|
it "Should be able to save" do
|
130
130
|
expect_keystroke("s", :command)
|
131
131
|
subject.save
|
132
132
|
end
|
133
133
|
|
134
134
|
it "Should be able to save as a file without duplicate being available" do
|
135
|
-
subject.
|
136
|
-
subject.
|
137
|
-
|
135
|
+
expect(subject).to receive(:save_pops_up_dialog?).and_return(false)
|
136
|
+
expect(subject).to receive(:duplicate_available?).and_return(false)
|
137
|
+
|
138
138
|
expect_keystroke("s", [:command, :shift])
|
139
|
-
subject.
|
140
|
-
|
139
|
+
expect(subject).to receive(:wait_for_save_dialog_and_save_file).with("filename")
|
140
|
+
|
141
141
|
subject.save_as("filename")
|
142
142
|
end
|
143
143
|
|
144
144
|
it "Should be able to save as a file using the duplicate..." do
|
145
|
-
subject.
|
146
|
-
subject.
|
145
|
+
expect(subject).to receive(:save_pops_up_dialog?).and_return(false)
|
146
|
+
expect(subject).to receive(:duplicate_available?).and_return(true)
|
147
147
|
|
148
|
-
subject.
|
149
|
-
subject.
|
150
|
-
subject.
|
148
|
+
expect(subject).to receive(:duplicate_and_close_original)
|
149
|
+
expect(subject).to receive(:save)
|
150
|
+
expect(subject).to receive(:wait_for_save_dialog_and_save_file).with("filename")
|
151
151
|
subject.save_as("filename")
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
it "Should be able to use normal Save when that pops up a dialog instead of save_as" do
|
155
|
-
subject.
|
156
|
-
subject.
|
157
|
-
subject.
|
155
|
+
expect(subject).to receive(:save_pops_up_dialog?).and_return(true)
|
156
|
+
expect(subject).to receive(:save)
|
157
|
+
expect(subject).to receive(:wait_for_save_dialog_and_save_file).with("filename")
|
158
158
|
subject.save_as("filename")
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
161
|
it "Should be able to wait for a save dialog and save the file" do
|
162
162
|
expect_wait_until_exists(at.sheet(1))
|
163
|
-
subject.
|
164
|
-
save_dialog.
|
163
|
+
expect(subject).to receive(:create_dialog).with(Osaka::TypicalSaveDialog, at.sheet(1)).and_return(save_dialog)
|
164
|
+
expect(save_dialog).to receive(:save).with("/tmp/filename")
|
165
165
|
expect_set_current_window("filename")
|
166
166
|
subject.wait_for_save_dialog_and_save_file("/tmp/filename")
|
167
167
|
end
|
168
|
-
|
168
|
+
|
169
169
|
it "Should be able to pick a file from an open dialog" do
|
170
|
-
dialog_mock =
|
171
|
-
subject.
|
172
|
-
dialog_mock.
|
173
|
-
dialog_mock.
|
174
|
-
|
170
|
+
dialog_mock = double("Open Dialog")
|
171
|
+
expect(subject).to receive(:create_dialog).with(Osaka::TypicalOpenDialog, at.window("dialog")).and_return(dialog_mock)
|
172
|
+
expect(dialog_mock).to receive(:set_folder).with("/tmp")
|
173
|
+
expect(dialog_mock).to receive(:select_file).with("filename")
|
174
|
+
|
175
175
|
subject.select_file_from_open_dialog("/tmp/filename", at.window("dialog"))
|
176
176
|
end
|
177
|
-
|
178
|
-
|
177
|
+
|
178
|
+
|
179
179
|
it "Should be able to duplicate and close the original document" do
|
180
|
-
subject.
|
181
|
-
subject.
|
180
|
+
allow(subject).to receive_message_chain(:duplicate, :control).and_return(new_instance_control)
|
181
|
+
expect(subject).to receive(:close)
|
182
182
|
subject.duplicate_and_close_original
|
183
|
-
subject.control.
|
183
|
+
expect(subject.control).to eq(new_instance_control)
|
184
184
|
end
|
185
|
-
|
185
|
+
|
186
186
|
it "Should be able to check whether Duplicate is supported" do
|
187
187
|
expect_exists?(at.menu_item("Duplicate").menu(1).menu_bar_item("File").menu_bar(1)).and_return(true)
|
188
|
-
subject.duplicate_available
|
188
|
+
expect(subject.duplicate_available?).to eq true
|
189
189
|
end
|
190
|
-
|
190
|
+
|
191
191
|
it "Should throw an exception when duplicate is not available"do
|
192
|
-
subject.
|
192
|
+
expect(subject).to receive(:duplicate_available?).and_return(false)
|
193
193
|
expect {subject.duplicate}.to raise_error(Osaka::VersioningError, "MacOS Versioning Error: Duplicate is not available on this Mac version")
|
194
194
|
end
|
195
195
|
|
196
196
|
it "Should return a new keynote instance variable after duplication (Lion!)" do
|
197
197
|
simulate_mac_version(:lion)
|
198
|
-
subject.
|
199
|
-
|
198
|
+
expect(subject).to receive(:duplicate_available?).and_return(true)
|
199
|
+
|
200
200
|
expect_click_menu_bar(at.menu_item("Duplicate"), "File")
|
201
|
-
subject.
|
201
|
+
expect(subject).to receive(:do_and_wait_for_new_window).and_yield.and_return("duplicate window")
|
202
202
|
|
203
|
-
subject.
|
204
|
-
subject.duplicate.control.
|
203
|
+
allow(subject).to receive_message_chain(:clone, :control).and_return(new_instance_control)
|
204
|
+
expect(subject.duplicate.control).to eq(new_instance_control)
|
205
205
|
end
|
206
|
-
|
206
|
+
|
207
207
|
it "Should return a new keynote instance variable after duplication" do
|
208
|
-
subject.
|
208
|
+
expect(subject).to receive(:duplicate_available?).and_return(true)
|
209
209
|
|
210
210
|
expect_click_menu_bar(at.menu_item("Duplicate"), "File")
|
211
|
-
subject.
|
211
|
+
expect(subject).to receive(:do_and_wait_for_new_window).and_yield.and_return("duplicate window", "New name duplicate window")
|
212
212
|
|
213
|
-
subject.
|
214
|
-
subject.
|
213
|
+
allow(subject).to receive_message_chain(:clone, :control).and_return(new_instance_control)
|
214
|
+
expect(subject).to receive(:sleep).with(0.4) # Avoiding Mountain Lion crash
|
215
215
|
expect_keystroke!(:return)
|
216
|
-
new_instance_control.
|
217
|
-
subject.duplicate.control.
|
216
|
+
expect(new_instance_control).to receive(:set_current_window).with("New name duplicate window")
|
217
|
+
expect(subject.duplicate.control).to eq(new_instance_control)
|
218
218
|
end
|
219
|
-
|
219
|
+
|
220
220
|
it "Should be able to check whether the save will pop up a dialog or not" do
|
221
221
|
expect_exists?(at.menu_item("Save…").menu(1).menu_bar_item("File").menu_bar(1)).and_return(true)
|
222
|
-
subject.save_pops_up_dialog
|
222
|
+
expect(subject.save_pops_up_dialog?).to eq true
|
223
223
|
end
|
224
|
-
|
224
|
+
|
225
225
|
end
|
226
|
-
|
226
|
+
|
227
227
|
it "Should be able to activate" do
|
228
228
|
expect_activate
|
229
229
|
subject.activate
|
230
230
|
end
|
231
|
-
|
231
|
+
|
232
232
|
it "Should be able to activate and launch. This is done because activate alone in Lion lead to strange behavior" do
|
233
233
|
simulate_mac_version(:lion)
|
234
234
|
expect_running?.and_return(false)
|
@@ -236,12 +236,12 @@ describe "Osaka::TypicalApplication" do
|
|
236
236
|
expect_activate
|
237
237
|
subject.activate
|
238
238
|
end
|
239
|
-
|
239
|
+
|
240
240
|
it "Should be able to focus" do
|
241
241
|
expect_focus
|
242
242
|
subject.focus
|
243
243
|
end
|
244
|
-
|
244
|
+
|
245
245
|
context "Copy pasting" do
|
246
246
|
|
247
247
|
it "Should be able to copy" do
|
@@ -251,16 +251,16 @@ describe "Osaka::TypicalApplication" do
|
|
251
251
|
|
252
252
|
it "Should be able to paste" do
|
253
253
|
expect_keystroke("v", :command)
|
254
|
-
subject.paste
|
254
|
+
subject.paste
|
255
255
|
end
|
256
256
|
|
257
257
|
it "Should be able to cut" do
|
258
258
|
expect_keystroke("x", :command)
|
259
259
|
subject.cut
|
260
260
|
end
|
261
|
-
|
261
|
+
|
262
262
|
end
|
263
|
-
|
263
|
+
|
264
264
|
context "Selecting things" do
|
265
265
|
it "Should be able to select all" do
|
266
266
|
expect_keystroke("a", :command)
|
@@ -269,33 +269,44 @@ describe "Osaka::TypicalApplication" do
|
|
269
269
|
end
|
270
270
|
|
271
271
|
context "Printing" do
|
272
|
-
|
272
|
+
|
273
273
|
it "Should be able to retrieve a print dialog" do
|
274
274
|
expect_keystroke("p", :command)
|
275
275
|
expect_wait_until_exists(at.sheet(1))
|
276
276
|
subject.print_dialog
|
277
277
|
end
|
278
278
|
end
|
279
|
-
|
279
|
+
|
280
280
|
context "Application info" do
|
281
281
|
it "Should be able to retrieve an application info object and parse it" do
|
282
282
|
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"}')
|
283
283
|
app_info = subject.get_info
|
284
|
-
app_info.name.
|
284
|
+
expect(app_info.name).to eq "ApplicationName.app"
|
285
285
|
end
|
286
286
|
end
|
287
|
-
|
287
|
+
|
288
288
|
context "Simple Application helpers to create objects" do
|
289
289
|
it "Should be able to create dialogs with a helper" do
|
290
|
-
Osaka::TypicalSaveDialog.
|
290
|
+
expect(Osaka::TypicalSaveDialog).to receive(:new).with(control.name, at.sheet(1) + control.base_location)
|
291
291
|
subject.create_dialog(Osaka::TypicalSaveDialog, at.sheet(1))
|
292
292
|
end
|
293
|
-
|
293
|
+
|
294
294
|
it "Should be able to create top level dialogs also with the helper" do
|
295
|
-
Osaka::TypicalSaveDialog.
|
295
|
+
expect(Osaka::TypicalSaveDialog).to receive(:new).with(control.name, at.window("toplevel"))
|
296
296
|
subject.create_dialog(Osaka::TypicalSaveDialog, at.window("toplevel"))
|
297
297
|
end
|
298
298
|
end
|
299
|
-
|
300
|
-
|
301
|
-
|
299
|
+
|
300
|
+
it "Should be able to check whether any standard windows are open and do nothing if there aren't" do
|
301
|
+
expect_standard_window_list.and_return([])
|
302
|
+
subject.raise_error_on_open_standard_windows("error message")
|
303
|
+
end
|
304
|
+
|
305
|
+
it "Should be able to check whether any standard windows are open and raise an error if so" do
|
306
|
+
expect_standard_window_list.and_return(["Window"])
|
307
|
+
expect {
|
308
|
+
subject.raise_error_on_open_standard_windows("error message")
|
309
|
+
}.to raise_error(Osaka::ApplicationWindowsMustBeClosed, "error message")
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|