osaka 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env rake
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,112 @@
1
+
2
+ module Osaka
3
+
4
+ class ApplicationWrapper
5
+
6
+ def initialize(name)
7
+ @name = name
8
+ end
9
+
10
+ def activate
11
+ tell("activate")
12
+ end
13
+
14
+ def quit
15
+ tell("quit")
16
+ end
17
+
18
+ def tell(command)
19
+ ScriptRunner::execute("tell application \"#{@name}\"; #{command}; end tell")
20
+ end
21
+
22
+ def system_event!(event)
23
+ ScriptRunner::execute("tell application \"System Events\"; tell process \"#{@name}\"; #{event}; end tell; end tell")
24
+ end
25
+
26
+ def system_event(event)
27
+ activate
28
+ system_event!(event)
29
+ end
30
+
31
+ def wait_until_exists!(element_to_wait_for)
32
+ system_event!("repeat until exists #{element_to_wait_for}; end repeat")
33
+ end
34
+
35
+ def wait_until_exists(element_to_wait_for)
36
+ activate
37
+ wait_until_exists!(element_to_wait_for)
38
+ end
39
+
40
+ def wait_until_not_exists!(element_to_wait_for)
41
+ system_event!("repeat until not exists #{element_to_wait_for}; end repeat")
42
+ end
43
+
44
+ def wait_until_not_exists(element_to_wait_for)
45
+ activate
46
+ wait_until_not_exists!(element_to_wait_for)
47
+ end
48
+
49
+ def construct_modifier_statement(modifier_keys)
50
+ modified_key_string = [ modifier_keys ].flatten.collect! { |mod_key| mod_key.to_s + " down"}.join(", ")
51
+ modifier_command = " using {#{modified_key_string}}" unless modifier_keys.empty?
52
+ modifier_command
53
+ end
54
+
55
+ def keystroke!(key, modifier_keys = [])
56
+ system_event!("keystroke \"#{key}\"#{construct_modifier_statement(modifier_keys)}")
57
+ end
58
+
59
+ def keystroke(key, modifier_keys = [])
60
+ activate
61
+ keystroke!(key, modifier_keys)
62
+ end
63
+
64
+ def keystroke_and_wait_until_exists!(key, modifier_keys, element)
65
+ keystroke!(key, modifier_keys)
66
+ wait_until_exists!(element)
67
+ end
68
+
69
+ def keystroke_and_wait_until_exists(key, modifier_keys, element)
70
+ activate
71
+ keystroke_and_wait_until_exists!(key, modifier_keys, element)
72
+ end
73
+
74
+ def click!(element)
75
+ system_event!("click #{element}")
76
+ end
77
+
78
+ def click(element)
79
+ activate
80
+ click!(element)
81
+ end
82
+
83
+ def click_and_wait_until_exists!(element, wait_condition)
84
+ click!(element)
85
+ wait_until_exists!(wait_condition)
86
+ end
87
+
88
+ def click_and_wait_until_exists(element, wait_condition)
89
+ activate
90
+ click_and_wait_until_exists!(element, wait_condition)
91
+ end
92
+
93
+ def click_and_wait_until_not_exists!(element, wait_condition)
94
+ click!(element)
95
+ wait_until_not_exists!(wait_condition)
96
+ end
97
+
98
+ def click_and_wait_until_not_exists(element, wait_condition)
99
+ activate
100
+ click_and_wait_until_not_exists!(element, wait_condition)
101
+ end
102
+
103
+ def set!(element, value)
104
+ system_event!("set #{element} to \"#{value}\"")
105
+ end
106
+
107
+ def set(element, value)
108
+ activate
109
+ set!(element, value)
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module Osaka
3
+
4
+ class KeynotePrintDialog < TypicalPrintDialog
5
+
6
+ end
7
+
8
+ class Keynote < TypicalApplication
9
+
10
+ def initialize
11
+ super "Keynote"
12
+ end
13
+
14
+ def create_print_dialog(location)
15
+ KeynotePrintDialog.new(location, app)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+
2
+ module Osaka
3
+ class Numbers < TypicalApplication
4
+
5
+ def initialize
6
+ super "Numbers"
7
+ end
8
+
9
+ def fill_cell(row, column, value)
10
+ @wrapper.tell("tell document 1; tell sheet 1; tell table 1; set value of cell #{column} of row #{row} to \"#{value}\"; end tell; end tell; end tell")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+
2
+ module Osaka
3
+ class PagesMailMergeDialog
4
+ attr_accessor :wrapper
5
+
6
+ def initialize(wrapper)
7
+ @wrapper = wrapper
8
+ end
9
+
10
+ def merge
11
+ @wrapper.click!('button "Merge" of sheet 1 of window 1')
12
+ print_dialog_location = 'window "Print"'
13
+ @wrapper.wait_until_exists!("menu button \"PDF\" of #{print_dialog_location}")
14
+ TypicalPrintDialog.new(print_dialog_location, @wrapper)
15
+ end
16
+
17
+ end
18
+
19
+ class Pages < TypicalApplication
20
+
21
+ def initialize
22
+ super "Pages"
23
+ end
24
+
25
+ def mail_merge
26
+ @wrapper.systemEvent("tell menu bar 1; tell menu \"Edit\"; click menu item 20; end tell; end tell")
27
+ @wrapper.wait_until_exists('button "Merge" of sheet 1 of window 1')
28
+ PagesMailMergeDialog.new(@wrapper)
29
+ end
30
+
31
+ def mail_merge_to_pdf(filename)
32
+ mail_merge_dialog = mail_merge
33
+ print_dialog = mail_merge_dialog.merge
34
+ print_dialog.save_as_pdf(filename)
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+
2
+ module Osaka
3
+
4
+ class ScriptRunnerError < RuntimeError
5
+ end
6
+
7
+ module ScriptRunner
8
+
9
+ @@debug_info_enabled = false
10
+
11
+ def self.enabled_debug_prints
12
+ @@debug_info_enabled = true
13
+ end
14
+
15
+ def self.disable_debug_prints
16
+ @@debug_info_enabled = false
17
+ end
18
+
19
+ def self.debug_prints?
20
+ @@debug_info_enabled
21
+ end
22
+
23
+ def self.execute(applescript)
24
+ script_commands = applescript.gsub('"', '\\"').split(';')
25
+ escaped_commands = ""
26
+ script_commands.each { |l|
27
+ escaped_commands += " -e \"#{l.strip}\""
28
+ }
29
+ puts "Executing: osascript#{escaped_commands}" if debug_prints?
30
+
31
+ raise(Osaka::ScriptRunnerError, "Error received while executing: #{applescript}") unless system("osascript#{escaped_commands}")
32
+ end
33
+
34
+ def self.execute_file(scriptName, parameters = "")
35
+ system("osascript #{scriptName} #{parameters}".strip)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,91 @@
1
+
2
+ module Osaka
3
+
4
+ class TypicalSaveDialog
5
+ attr_accessor :wrapper
6
+
7
+ def initialize(location, wrapper)
8
+ @location = location
9
+ @wrapper = wrapper
10
+ end
11
+
12
+ def set_filename(filename)
13
+ @wrapper.set("value of text field 1 of #{@location}", filename)
14
+ end
15
+
16
+ def set_folder(pathname)
17
+ @wrapper.keystroke_and_wait_until_exists("g", [ :command, :shift ], "sheet 1 of #{@location}")
18
+ @wrapper.set("value of text field 1 of sheet 1 of #{@location}", pathname)
19
+ @wrapper.click_and_wait_until_not_exists("button \"Go\" of sheet 1 of #{@location}", "sheet 1 of #{@location}")
20
+ end
21
+
22
+ def click_save
23
+ @wrapper.click_and_wait_until_not_exists("button \"Save\" of #{@location}", "#{@location}")
24
+ end
25
+
26
+ def save(filename)
27
+ set_filename(File.basename(filename))
28
+ set_folder(File.dirname(filename)) unless File.dirname(filename) == "."
29
+ click_save
30
+ end
31
+
32
+ end
33
+
34
+ class TypicalPrintDialog
35
+ attr_accessor :wrapper
36
+
37
+ def initialize(location, wrapper)
38
+ @location = location
39
+ @wrapper = wrapper
40
+ end
41
+
42
+ def create_save_dialog(location, app)
43
+ GenericSaveDialog.new(location, app)
44
+ end
45
+
46
+ def save_as_pdf(filename)
47
+ @wrapper.click_and_wait_until_exists!("menu button \"PDF\" of #{@location}", "menu 1 of menu button \"PDF\" of #{@location}")
48
+ @wrapper.click_and_wait_until_exists!("menu item 2 of menu 1 of menu button \"PDF\" of #{@location}", 'window "Save"')
49
+ save_dialog = create_save_dialog("window \"Save\"", @wrapper)
50
+ save_dialog.save(filename)
51
+ @wrapper.wait_until_not_exists(@location)
52
+ end
53
+ end
54
+
55
+ class TypicalApplication
56
+
57
+ attr_accessor :wrapper
58
+
59
+ def initialize(name)
60
+ @wrapper = ApplicationWrapper.new(name)
61
+ end
62
+
63
+ def open (filename)
64
+ abolutePathFileName = File.absolute_path(filename)
65
+ @wrapper.tell("open \"#{abolutePathFileName}\"")
66
+ end
67
+
68
+ def quit
69
+ @wrapper.quit
70
+ end
71
+
72
+ def save
73
+ @wrapper.keystroke("s", :command)
74
+ end
75
+
76
+ def activate
77
+ @wrapper.activate
78
+ end
79
+
80
+ def create_print_dialog(location)
81
+ TypicalPrintDialog.new(location, @wrapper)
82
+ end
83
+
84
+ def print_dialog
85
+ location = "sheet 1 of window 1"
86
+ @wrapper.keystroke_and_wait_until_exists("p", :command, location)
87
+ create_print_dialog(location)
88
+ end
89
+
90
+ end
91
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module Osaka
3
+ VERSION = "0.1.0"
4
+ end
data/lib/osaka.rb ADDED
@@ -0,0 +1,7 @@
1
+
2
+ require 'osaka/scriptrunner'
3
+ require 'osaka/applicationwrapper'
4
+ require 'osaka/typicalapplication'
5
+ require 'osaka/pages'
6
+ require 'osaka/numbers'
7
+ require 'osaka/keynote'
data/osaka.gemfile ADDED
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../lib/osaka/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'osaka'
6
+ gem.version = Osaka::VERSION
7
+ gem.date = Date.today.to_s
8
+
9
+ gem.summary = "Osaka is an Mac GUI automation library"
10
+ gem.description = "Osaka wraps osascript (Applescript) and provides a ruby interface for automating tasks through the GUI on Mac"
11
+
12
+ gem.authors = ['Bas Vodde']
13
+ gem.email = 'basv@odd-e.com'
14
+ gem.homepage = 'https://github.com/basvodde/osaka'
15
+
16
+ gem.add_dependency('rake')
17
+ gem.add_development_dependency('rspec', [">= 2.0.0"])
18
+
19
+ gem.files = `git ls-files -- {.,test,spec,lib}/*`.split("\n")
20
+ end
@@ -0,0 +1,144 @@
1
+
2
+ require 'osaka'
3
+
4
+ describe "Osaka::ApplicationWrapper" do
5
+
6
+ name = "ApplicationName"
7
+ quoted_name = "\"#{name}\""
8
+ subject { Osaka::ApplicationWrapper.new(name) }
9
+
10
+ it "Should be able to tell applications to do something" do
11
+ Osaka::ScriptRunner.should_receive(:execute).with("tell application #{quoted_name}; command; end tell")
12
+ subject.tell("command")
13
+ end
14
+
15
+ it "Can also pass multi-line commands to telling an application what to do" do
16
+ Osaka::ScriptRunner.should_receive(:execute).with("tell application #{quoted_name}; activate; quit; end tell")
17
+ subject.tell("activate; quit")
18
+ end
19
+
20
+ it "Has a short-cut method for activation" do
21
+ Osaka::ScriptRunner.should_receive(:execute).with(/activate/)
22
+ subject.activate
23
+ end
24
+
25
+ it "Has a short-cut method for quitting" do
26
+ Osaka::ScriptRunner.should_receive(:execute).with(/quit/)
27
+ subject.quit
28
+ end
29
+
30
+ it "Should be able to generate events via the Systems Events" do
31
+ Osaka::ScriptRunner.should_receive(:execute).with(/tell application "System Events"; tell process #{quoted_name}; quit; end tell; end tell/)
32
+ subject.system_event!("quit")
33
+ end
34
+
35
+ it "Should be able to generate events via the Systems Events and activate the application first" do
36
+ subject.should_receive(:activate)
37
+ subject.should_receive(:system_event!).with("quit")
38
+ subject.system_event("quit")
39
+ end
40
+
41
+ it "Should be able to wait for for a specific element existing" do
42
+ Osaka::ScriptRunner.should_receive(:execute).with(/repeat until exists window 1; end repeat/)
43
+ subject.wait_until_exists!("window 1")
44
+ end
45
+
46
+ it "Should be able to wait until exists and activate the application first" do
47
+ subject.should_receive(:activate)
48
+ subject.should_receive(:wait_until_exists!).with("window 1")
49
+ subject.wait_until_exists("window 1")
50
+ end
51
+
52
+ it "Should be able to wait for a specific element to not exist anymore" do
53
+ Osaka::ScriptRunner.should_receive(:execute).with(/repeat until not exists window 1; end repeat/)
54
+ subject.wait_until_not_exists!("window 1")
55
+ end
56
+
57
+ it "Should be able to wait_until_not_exists and activate" do
58
+ subject.should_receive(:activate)
59
+ subject.should_receive(:wait_until_not_exists!).with("window 1")
60
+ subject.wait_until_not_exists("window 1")
61
+ end
62
+
63
+ it "Should be able to generate keystroke events" do
64
+ Osaka::ScriptRunner.should_receive(:execute).with(/keystroke "p"/)
65
+ subject.keystroke!("p")
66
+ end
67
+
68
+ it "Should be able to keystroke and activate" do
69
+ subject.should_receive(:activate)
70
+ subject.should_receive(:keystroke!).with("a", [])
71
+ subject.keystroke("a", [])
72
+ end
73
+
74
+ it "Should be able to do keystrokes with command down" do
75
+ Osaka::ScriptRunner.should_receive(:execute).with(/keystroke "p" using {command down}/)
76
+ subject.keystroke!("p", :command)
77
+ end
78
+
79
+ it "Should be able to do keystrokes with option and command down" do
80
+ Osaka::ScriptRunner.should_receive(:execute).with(/keystroke "p" using {option down, command down}/)
81
+ subject.keystroke!("p", [ :option, :command ])
82
+ end
83
+
84
+ it "Should be able to do a keystroke and wait until something happen in one easy command" do
85
+ subject.should_receive(:keystroke!).with("p", [])
86
+ subject.should_receive(:wait_until_exists!).with("window 1")
87
+ subject.keystroke_and_wait_until_exists!("p", [], "window 1")
88
+ end
89
+
90
+ it "Should be able to keystroke_and_wait_until_exists and activate" do
91
+ subject.should_receive(:activate)
92
+ subject.should_receive(:keystroke_and_wait_until_exists!).with("p", [], "window 1")
93
+ subject.keystroke_and_wait_until_exists("p", [], "window 1")
94
+ end
95
+
96
+ it "Should be able to do clicks" do
97
+ Osaka::ScriptRunner.should_receive(:execute).with(/click menu button "PDF"/)
98
+ subject.click!('menu button "PDF"')
99
+ end
100
+
101
+ it "Should be able to do click and activate" do
102
+ subject.should_receive(:activate)
103
+ subject.should_receive(:click!).with("button")
104
+ subject.click("button")
105
+ end
106
+
107
+ it "Should be able to do clicks and wait until something happened in one easy command" do
108
+ subject.should_receive(:click!).with("button")
109
+ subject.should_receive(:wait_until_exists!).with("window")
110
+ subject.click_and_wait_until_exists!("button", "window")
111
+ end
112
+
113
+ it "Should be able to click_and_wait_until_exists and activate" do
114
+ subject.should_receive(:activate)
115
+ subject.should_receive(:click_and_wait_until_exists!).with("button", "window")
116
+ subject.click_and_wait_until_exists("button", "window")
117
+ end
118
+
119
+ it "Should be able to click and wait until something doesn't exist anymore" do
120
+ subject.should_receive(:click!).with("button1")
121
+ subject.should_receive(:wait_until_not_exists!).with("window 1")
122
+ subject.click_and_wait_until_not_exists!('button1', 'window 1')
123
+ end
124
+
125
+ it "Should be able to click_and_wait_until_not_exists and activate" do
126
+ subject.should_receive(:activate)
127
+ subject.should_receive(:click_and_wait_until_not_exists!).with("button", "window")
128
+ subject.click_and_wait_until_not_exists('button', 'window')
129
+ end
130
+
131
+ it "Should be able to set a value to an element" do
132
+ subject.should_receive(:system_event!).with(/set value of window to "newvalue"/)
133
+ subject.set!("value of window", "newvalue")
134
+ end
135
+
136
+ it "Should be able to set a value and activate" do
137
+ subject.should_receive(:activate)
138
+ subject.should_receive(:set!).with("value of window", "newvalue")
139
+ subject.set("value of window", "newvalue")
140
+ end
141
+
142
+
143
+
144
+ end
@@ -0,0 +1,11 @@
1
+
2
+ require 'osaka'
3
+
4
+ describe "Osaka::Keynote" do
5
+
6
+ subject { Osaka::Keynote.new }
7
+
8
+ before (:each) do
9
+ subject.wrapper = double("Osaka::ApplicationWrapper").as_null_object
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+
2
+ require 'osaka'
3
+
4
+ describe "Osaka::Numbers" do
5
+
6
+ subject { Osaka::Numbers.new }
7
+
8
+ before (:each) do
9
+ subject.wrapper = double("Osaka::Number").as_null_object
10
+ end
11
+
12
+ it "Should be able to fill in data in cells" do
13
+ subject.wrapper.should_receive(:tell).with('tell document 1; tell sheet 1; tell table 1; set value of cell 2 of row 1 to "30"; end tell; end tell; end tell')
14
+ subject.fill_cell(1, 2, "30")
15
+ end
16
+
17
+ end
@@ -0,0 +1,37 @@
1
+
2
+ require 'osaka'
3
+
4
+ describe "Osaka::Pages" do
5
+
6
+ subject { Osaka::Pages.new }
7
+
8
+ before (:each) do
9
+ subject.wrapper = double("Osaka::ApplicationWrapper").as_null_object
10
+ end
11
+
12
+ it "Should be able to do mail merge to a PDF flow" do
13
+
14
+ mail_merge_dialog = double(:PagesMailMergeDialog)
15
+ print_dialog = double(:GenericPrintDialog)
16
+
17
+ subject.should_receive(:mail_merge).and_return(mail_merge_dialog)
18
+ mail_merge_dialog.should_receive(:merge).and_return(print_dialog)
19
+ print_dialog.should_receive(:save_as_pdf).with("filename")
20
+
21
+ subject.mail_merge_to_pdf("filename")
22
+
23
+ end
24
+
25
+ it "Should be able to select the Mail Merge" do
26
+ subject.wrapper.should_receive(:systemEvent).with("tell menu bar 1; tell menu \"Edit\"; click menu item 20; end tell; end tell")
27
+ subject.wrapper.should_receive(:wait_until_exists).with('button "Merge" of sheet 1 of window 1')
28
+ subject.mail_merge
29
+ end
30
+
31
+ it "Should click the merge button of the mail merge dialog" do
32
+ subject.wrapper.should_receive(:click!).with('button "Merge" of sheet 1 of window 1')
33
+ subject.wrapper.should_receive(:wait_until_exists!).with('menu button "PDF" of window "Print"')
34
+ subject.mail_merge.merge
35
+ end
36
+
37
+ end
@@ -0,0 +1,50 @@
1
+ require 'osaka'
2
+
3
+ describe "Osaka::ScriptRunner" do
4
+
5
+ subject { Osaka::ScriptRunner }
6
+
7
+ it "Should be able to run single-line text as osascript" do
8
+ subject.should_receive(:system).with('osascript -e "random number"').and_return(true)
9
+ subject.execute("random number")
10
+ end
11
+
12
+ it "Should escape quotes when passing text" do
13
+ subject.should_receive(:system).with('osascript -e "say \\"hello\\""').and_return(true)
14
+ subject.execute('say "hello"')
15
+ end
16
+
17
+ it "Should be able to run on debug printing" do
18
+ subject.should_receive(:system).and_return(true)
19
+ subject.should_receive(:puts).with('Executing: osascript -e "random number"')
20
+ Osaka::ScriptRunner::enabled_debug_prints
21
+ subject.execute("random number")
22
+ Osaka::ScriptRunner::disable_debug_prints
23
+ end
24
+
25
+ it "Should not print any debugging information by default " do
26
+ subject.should_receive(:system).and_return(true)
27
+ subject.should_not_receive(:puts)
28
+ subject.execute("random number")
29
+ end
30
+
31
+ it "Should be able to define multi-line statements using ; as a separator" do
32
+ subject.should_receive(:system).with('osascript -e "tell application \\"Calculator\\"" -e "activate" -e "end tell"').and_return(true)
33
+ subject.execute('tell application "Calculator"; activate; end tell')
34
+ end
35
+
36
+ it "Should raise an exception witha proper error message when the applescript fails" do
37
+ subject.should_receive(:system).and_return(false)
38
+ lambda {subject.execute("Fuck off!")}.should raise_error(Osaka::ScriptRunnerError, "Error received while executing: Fuck off!")
39
+ end
40
+
41
+ it "Should be able to execute an file containing applescript" do
42
+ subject.should_receive(:system).with('osascript script.scpt').and_return(true)
43
+ subject.execute_file("script.scpt")
44
+ end
45
+
46
+ it "Should be able to pass parameters to an applescript" do
47
+ subject.should_receive(:system).with('osascript script.scpt a b c').and_return(true)
48
+ subject.execute_file("script.scpt", "a b c")
49
+ end
50
+ end
@@ -0,0 +1,95 @@
1
+
2
+ require 'osaka'
3
+
4
+ describe "Osaka::TypicalApplication" do
5
+
6
+ subject { Osaka::TypicalApplication.new("ApplicationName") }
7
+
8
+ before (:each) do
9
+ subject.wrapper = double("Osaka::ApplicationWrapper").as_null_object
10
+ end
11
+
12
+ it "Should pass the right open string to the Keynote application osascript" do
13
+ filename = "filename.key"
14
+ subject.wrapper.should_receive(:tell).with("open \"#{File.absolute_path(filename)}\"")
15
+ subject.open(filename)
16
+ end
17
+
18
+ it "Should be able to quit" do
19
+ subject.wrapper.should_receive(:quit)
20
+ subject.quit
21
+ end
22
+
23
+ it "Should be able to save" do
24
+ subject.wrapper.should_receive(:keystroke).with("s", :command)
25
+ subject.save
26
+ end
27
+
28
+ it "Should be able to activate keynote" do
29
+ subject.wrapper.should_receive(:activate)
30
+ subject.activate
31
+ end
32
+
33
+ it "Should be able to retrieve a print dialog" do
34
+ subject.wrapper.should_receive(:keystroke_and_wait_until_exists).with("p", :command, "sheet 1 of window 1")
35
+ subject.print_dialog
36
+ end
37
+
38
+ describe "Generic Print Dialog" do
39
+
40
+ location = "window 1"
41
+ subject { Osaka::TypicalPrintDialog.new("window 1", double(:OSAApp).as_null_object) }
42
+
43
+ it "Should be able to save the PDF in a print dialog" do
44
+ save_dialog_mock = double(:GenericSaveDialog)
45
+ subject.wrapper.should_receive(:click_and_wait_until_exists!).with('menu button "PDF" of window 1', 'menu 1 of menu button "PDF" of window 1')
46
+ subject.wrapper.should_receive(:click_and_wait_until_exists!).with('menu item 2 of menu 1 of menu button "PDF" of window 1', 'window "Save"')
47
+ subject.should_receive(:create_save_dialog).with("window \"Save\"", subject.wrapper).and_return(save_dialog_mock)
48
+ save_dialog_mock.should_receive(:save).with("filename")
49
+ subject.wrapper.should_receive(:wait_until_not_exists).with('window 1')
50
+ subject.save_as_pdf("filename")
51
+ end
52
+ end
53
+
54
+ describe "Generic Save Dialog" do
55
+
56
+ subject { Osaka::TypicalSaveDialog.new("window 1", double("Osaka::ApplicationWrapper").as_null_object)}
57
+
58
+ it "Should set the filename in the test field" do
59
+ subject.should_receive(:set_filename).with("filename")
60
+ subject.should_receive(:click_save)
61
+ subject.should_not_receive(:set_folder)
62
+ subject.save("filename")
63
+ end
64
+
65
+ it "Should pick only the base filename when a path is given" do
66
+ subject.should_receive(:set_filename).with("filename")
67
+ subject.should_receive(:set_folder)
68
+ subject.should_receive(:click_save)
69
+ subject.save("/path/filename")
70
+ end
71
+
72
+ it "Should set the path when a full path is given" do
73
+ subject.should_receive(:set_filename)
74
+ subject.should_receive(:set_folder).with("/path/second")
75
+ subject.save("/path/second/name")
76
+ end
77
+
78
+ it "Should be able to click save" do
79
+ subject.wrapper.should_receive(:click_and_wait_until_not_exists).with('button "Save" of window 1', 'window 1')
80
+ subject.click_save
81
+ end
82
+
83
+ it "Should be able to set the filename" do
84
+ subject.wrapper.should_receive(:set).with('value of text field 1 of window 1', "filename")
85
+ subject.set_filename("filename")
86
+ end
87
+
88
+ it "Should be able to set the path" do
89
+ subject.wrapper.should_receive(:keystroke_and_wait_until_exists).with("g", [ :command, :shift ], "sheet 1 of window 1")
90
+ subject.wrapper.should_receive(:set).with("value of text field 1 of sheet 1 of window 1", "path")
91
+ subject.wrapper.should_receive(:click_and_wait_until_not_exists).with('button "Go" of sheet 1 of window 1', "sheet 1 of window 1")
92
+ subject.set_folder("path")
93
+ end
94
+ end
95
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: osaka
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Bas Vodde
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-02-10 00:00:00 +08:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rake
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 2.0.0
36
+ type: :development
37
+ version_requirements: *id002
38
+ description: Osaka wraps osascript (Applescript) and provides a ruby interface for automating tasks through the GUI on Mac
39
+ email: basv@odd-e.com
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files: []
45
+
46
+ files:
47
+ - README
48
+ - Rakefile
49
+ - lib/osaka.rb
50
+ - lib/osaka/applicationwrapper.rb
51
+ - lib/osaka/keynote.rb
52
+ - lib/osaka/numbers.rb
53
+ - lib/osaka/pages.rb
54
+ - lib/osaka/scriptrunner.rb
55
+ - lib/osaka/typicalapplication.rb
56
+ - lib/osaka/version.rb
57
+ - osaka.gemfile
58
+ - spec/applicationwrapper_spec.rb
59
+ - spec/keynote_spec.rb
60
+ - spec/numbers_spec.rb
61
+ - spec/pages_spec.rb
62
+ - spec/scriptrunner_spec.rb
63
+ - spec/typicalapplication_spec.rb
64
+ has_rdoc: true
65
+ homepage: https://github.com/basvodde/osaka
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.6.2
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Osaka is an Mac GUI automation library
92
+ test_files: []
93
+