osaka 0.1.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.
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
+