osaka 0.4.8 → 0.4.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +7 -0
  3. data/README.rdoc +1 -1
  4. data/Rakefile +12 -2
  5. data/lib/osaka.rb +6 -0
  6. data/lib/osaka/calculator.rb +1 -1
  7. data/lib/osaka/commandrunner.rb +17 -0
  8. data/lib/osaka/defaultssystem.rb +28 -0
  9. data/lib/osaka/keynote.rb +8 -6
  10. data/lib/osaka/keynoteflow.rb +10 -2
  11. data/lib/osaka/launchservices.rb +29 -0
  12. data/lib/osaka/location.rb +1 -1
  13. data/lib/osaka/mailmergeflow.rb +1 -1
  14. data/lib/osaka/numbers.rb +1 -1
  15. data/lib/osaka/osakaexpectations.rb +65 -61
  16. data/lib/osaka/pages.rb +35 -26
  17. data/lib/osaka/preview.rb +1 -1
  18. data/lib/osaka/remotecontrol.rb +57 -47
  19. data/lib/osaka/scriptrunner.rb +2 -11
  20. data/lib/osaka/textedit.rb +1 -1
  21. data/lib/osaka/typicalapplication.rb +10 -4
  22. data/lib/osaka/typicalfinderdialog.rb +1 -1
  23. data/lib/osaka/typicalopendialog.rb +22 -18
  24. data/lib/osaka/typicalprintdialog.rb +1 -1
  25. data/lib/osaka/typicalsavedialog.rb +1 -1
  26. data/lib/osaka/version.rb +1 -1
  27. data/{osaka.gemfile → osaka.gemspec} +0 -0
  28. data/spec/assets/document.pdf +0 -0
  29. data/spec/calculator_spec.rb +5 -5
  30. data/spec/defaultssystem_spec.rb +30 -0
  31. data/spec/integration_calculator_spec.rb +7 -7
  32. data/spec/integration_keynote_spec.rb +24 -11
  33. data/spec/integration_numbers_spec.rb +2 -2
  34. data/spec/integration_pages_numbers_mail_merge_spec.rb +9 -9
  35. data/spec/integration_preview_spec.rb +16 -0
  36. data/spec/integration_textedit_spec.rb +5 -5
  37. data/spec/keynote_flows_spec.rb +52 -31
  38. data/spec/keynote_spec.rb +24 -14
  39. data/spec/launchservices_spec.rb +63 -0
  40. data/spec/location_spec.rb +13 -13
  41. data/spec/mailmergeflow_spec.rb +13 -13
  42. data/spec/numbers_spec.rb +10 -10
  43. data/spec/osakaexpectations_spec.rb +3 -3
  44. data/spec/pages_spec.rb +80 -61
  45. data/spec/preview_spec.rb +5 -5
  46. data/spec/remotecontrol_spec.rb +65 -43
  47. data/spec/scriptrunner_spec.rb +22 -22
  48. data/spec/textedit_spec.rb +3 -3
  49. data/spec/typicalapplication_spec.rb +119 -108
  50. data/spec/typicalfinderdialog_spec.rb +2 -2
  51. data/spec/typicalopendialog_spec.rb +41 -35
  52. data/spec/typicalprintdialog_spec.rb +5 -5
  53. data/spec/typicalsavedialog_spec.rb +10 -10
  54. metadata +51 -47
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 854d5b4239636f0440e333079786058eb04104d5
4
+ data.tar.gz: 05d82bb53d115828c0545585288c1d5c155097ff
5
+ SHA512:
6
+ metadata.gz: 98ac0bf615f682f2fe15913e42c4785bff36a0635e46745a43fc4c4d6329f1e5d3529ed7539727a4e8c69f2f31ef888f5f109926ea9b9ddf26e3f5e167b948ce
7
+ data.tar.gz: abb76f7009b18c85e62847f563a3aa6384e4ebfa742d24396dbeee73de36c7fd6cb140adca7d7c90e0622a059d354e28949361e7e8382067ad25f9bbd62b6188
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'rspec', '~> 3.1'
7
+ end
data/README.rdoc CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  Osaka - apple OSA script Kontrolling the Application (OSAKA :P)
3
- This is a Ruby 1.9 library for automating work via GUI on Mac (using OSA/Applescript)
3
+ This is a Ruby library for automating work via GUI on Mac (using OSA/Applescript)
4
4
 
5
5
  = How to install
6
6
 
data/Rakefile CHANGED
@@ -1,6 +1,16 @@
1
1
  #!/usr/bin/env rake
2
2
  require 'rspec/core/rake_task'
3
3
 
4
- RSpec::Core::RakeTask.new(:spec)
4
+ task :default => :all
5
5
 
6
- task :default => :spec
6
+ desc "Run the spec tasks"
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.rspec_opts = ["--tag ~integration"]
9
+ end
10
+
11
+ desc "Run the integration tests"
12
+ RSpec::Core::RakeTask.new(:integration) do |t|
13
+ t.rspec_opts = ["--tag integration"]
14
+ end
15
+
16
+ RSpec::Core::RakeTask.new(:all)
data/lib/osaka.rb CHANGED
@@ -1,5 +1,11 @@
1
1
 
2
+ # Non UI servies
3
+ require 'osaka/commandrunner'
2
4
  require 'osaka/scriptrunner'
5
+ require 'osaka/launchservices'
6
+ require 'osaka/defaultssystem'
7
+
8
+ # Basic UI automation
3
9
  require 'osaka/location'
4
10
  require 'osaka/remotecontrol'
5
11
  require 'osaka/typicalapplication'
@@ -31,4 +31,4 @@ module Osaka
31
31
  control.get!('value', at.static_text(1).group(1))
32
32
  end
33
33
  end
34
- end
34
+ end
@@ -0,0 +1,17 @@
1
+
2
+ # encoding: utf-8
3
+
4
+ module Osaka
5
+
6
+ class SystemCommandFailed < RuntimeError
7
+ end
8
+
9
+ module CommandRunner
10
+ def self.run(command)
11
+ output = `#{command} 2>&1`
12
+ raise Osaka::SystemCommandFailed, "message" + output unless $?.success?
13
+ output
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,28 @@
1
+ require 'json'
2
+
3
+ class DefaultsSystem
4
+
5
+
6
+ def initialize(domain)
7
+ @domain = domain
8
+ @settings = {}
9
+ parse_settings_file(Osaka::CommandRunner.run("defaults read #{domain}"))
10
+ end
11
+
12
+ def parse_settings_file (settings_from_defaults)
13
+ scanner = StringScanner.new (settings_from_defaults)
14
+ scanner.scan(/{\n/)
15
+ while scanner.scan(/\s+(.*) = (.*);\n/) do
16
+ @settings[scanner[1]] = scanner[2]
17
+ end
18
+ end
19
+
20
+ def [](key)
21
+ @settings[key]
22
+ end
23
+
24
+ def []=(key, value)
25
+ Osaka::CommandRunner.run("defaults write #{@domain} #{key} #{value}")
26
+ end
27
+
28
+ end
data/lib/osaka/keynote.rb CHANGED
@@ -16,12 +16,14 @@ module Osaka
16
16
  end
17
17
 
18
18
  def select_all_slides
19
- if control.exists?(at.button("Slides").group(1).outline(1).scroll_area(2).splitter_group(1).splitter_group(1))
20
- control.click(at.button("Slides").group(1).outline(1).scroll_area(2).splitter_group(1).splitter_group(1))
21
- else
22
- control.click(at.button("Slides").group(1).outline(1).scroll_area(1).splitter_group(1).splitter_group(1))
23
- end
19
+ light_table_view
24
20
  select_all
25
21
  end
22
+
23
+ def light_table_view
24
+ if control.exists?(at.menu_item("Light Table").menu(1).menu_bar_item("View").menu_bar(1))
25
+ control.click(at.menu_item("Light Table").menu(1).menu_bar_item("View").menu_bar(1))
26
+ end
27
+ end
26
28
  end
27
- end
29
+ end
@@ -1,22 +1,29 @@
1
1
 
2
2
  module CommonFlows
3
+
3
4
  def self.keynote_combine_files(result_file, files_to_merge)
4
5
  keynote = Osaka::Keynote.new
6
+ keynote.activate
7
+ keynote.raise_error_on_open_standard_windows("All Keynote windows must be closed before running this flow")
8
+
5
9
  files_to_merge = [files_to_merge].flatten
6
10
  keynote.open(files_to_merge.shift)
11
+ keynote.light_table_view
7
12
  keynote.save_as(result_file)
8
13
 
14
+
9
15
  files_to_merge.each { |file|
10
16
  combine_keynote = Osaka::Keynote.new
11
17
  combine_keynote.open(file)
12
18
  combine_keynote.select_all_slides
13
19
  combine_keynote.copy
20
+ combine_keynote.close
14
21
  keynote.select_all_slides
15
22
  keynote.paste
16
- combine_keynote.close
17
23
  }
18
24
 
19
25
  keynote.save
26
+ keynote.close
20
27
  keynote.quit
21
28
  end
22
29
 
@@ -26,4 +33,5 @@ module CommonFlows
26
33
  files_to_open = files_in_directory.collect { |f| File.join(directory, f)}
27
34
  keynote_combine_files(result_file, files_to_open.sort)
28
35
  end
29
- end
36
+
37
+ end
@@ -0,0 +1,29 @@
1
+
2
+ module Osaka
3
+ module LaunchServices
4
+
5
+ def self.dump
6
+ Osaka::CommandRunner.run("/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump")
7
+ end
8
+
9
+ def self.retrieve(bundle_name)
10
+ launch_services_dump = Osaka::CommandRunner.run("/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -dump")
11
+ current_hash = {}
12
+ launch_services_hash = {}
13
+
14
+ launch_services_dump.each_line do |line|
15
+ if line =~ /^(\w.*):\s+(\w.*)$/
16
+ launch_services_hash[current_hash[:name]] = current_hash
17
+ current_hash = {:id => $2}
18
+ end
19
+ if line =~ /^\t(\w.*):\s+(\w.*)$/
20
+ current_hash[$1.to_sym] = $2
21
+ #puts current_hash
22
+ end
23
+ end
24
+ launch_services_hash[current_hash[:name]] = current_hash
25
+ launch_services_hash[bundle_name]
26
+ end
27
+
28
+ end
29
+ end
@@ -153,4 +153,4 @@ end
153
153
 
154
154
  def at
155
155
  Osaka::Location.new ""
156
- end
156
+ end
@@ -16,4 +16,4 @@ module CommonFlows
16
16
  pages.close(:dont_save)
17
17
  pages.quit(:dont_save)
18
18
  end
19
- end
19
+ end
data/lib/osaka/numbers.rb CHANGED
@@ -50,4 +50,4 @@ module Osaka
50
50
 
51
51
 
52
52
  end
53
- end
53
+ end
@@ -1,132 +1,136 @@
1
1
 
2
2
  module Osaka
3
3
  module OsakaExpectations
4
-
4
+
5
5
  def simulate_mac_version(version)
6
- control.should_receive(:mac_version).and_return(version)
6
+ expect(control).to receive(:mac_version).and_return(version)
7
7
  end
8
-
8
+
9
9
  def expect_execute_osascript(command = nil)
10
- return Osaka::ScriptRunner.should_receive(:execute).with(command) unless command.nil?
11
- Osaka::ScriptRunner.should_receive(:execute)
10
+ return expect(Osaka::ScriptRunner).to receive(:execute).with(command) unless command.nil?
11
+ expect(Osaka::ScriptRunner).to receive(:execute)
12
12
  end
13
-
13
+
14
14
  def expect_clone
15
- control.should_receive(:clone)
15
+ expect(control).to receive(:clone)
16
16
  end
17
-
17
+
18
18
  def expect_activate
19
- control.should_receive(:activate)
19
+ expect(control).to receive(:activate)
20
20
  end
21
21
 
22
22
  def expect_launch
23
- control.should_receive(:launch)
23
+ expect(control).to receive(:launch)
24
24
  end
25
-
25
+
26
26
  def expect_focus
27
- control.should_receive(:focus)
27
+ expect(control).to receive(:focus)
28
28
  end
29
29
 
30
30
  def expect_focus!
31
- control.should_receive(:focus!)
31
+ expect(control).to receive(:focus!)
32
32
  end
33
-
33
+
34
34
  def expect_set_current_window(name)
35
- control.should_receive(:set_current_window).with(name)
35
+ expect(control).to receive(:set_current_window).with(name)
36
36
  end
37
-
37
+
38
38
  def expect_running?
39
- control.should_receive(:running?)
39
+ expect(control).to receive(:running?)
40
40
  end
41
-
41
+
42
42
  def expect_quit
43
- control.should_receive(:quit)
43
+ expect(control).to receive(:quit)
44
44
  end
45
-
45
+
46
46
  def expect_window_list
47
- control.should_receive(:window_list)
47
+ expect(control).to receive(:window_list)
48
+ end
49
+
50
+ def expect_standard_window_list
51
+ expect(control).to receive(:standard_window_list)
48
52
  end
49
-
53
+
50
54
  def expect_current_window_name
51
- control.should_receive(:current_window_name)
55
+ expect(control).to receive(:current_window_name)
52
56
  end
53
-
57
+
54
58
  def expect_set(element, location, value)
55
- control.should_receive(:set).with(element, location, value)
59
+ expect(control).to receive(:set).with(element, location, value)
56
60
  end
57
61
 
58
62
  def expect_set!(element, location, value)
59
- control.should_receive(:set!).with(element, location, value)
63
+ expect(control).to receive(:set!).with(element, location, value)
60
64
  end
61
-
65
+
62
66
  def expect_get_app!(element)
63
- control.should_receive(:get_app!).with(element)
67
+ expect(control).to receive(:get_app!).with(element)
64
68
  end
65
-
69
+
66
70
  def expect_keystroke(key, modifier = [])
67
- control.should_receive(:keystroke).with(key, modifier).and_return(control) unless modifier.empty?
68
- control.should_receive(:keystroke).with(key).and_return(control) if modifier.empty?
71
+ expect(control).to receive(:keystroke).with(key, modifier).and_return(control) unless modifier.empty?
72
+ expect(control).to receive(:keystroke).with(key).and_return(control) if modifier.empty?
69
73
  end
70
-
74
+
71
75
  def expect_keystroke!(key, modifier = [])
72
- control.should_receive(:keystroke!).with(key, modifier).and_return(control) unless modifier.empty?
73
- control.should_receive(:keystroke!).with(key).and_return(control) if modifier.empty?
76
+ expect(control).to receive(:keystroke!).with(key, modifier).and_return(control) unless modifier.empty?
77
+ expect(control).to receive(:keystroke!).with(key).and_return(control) if modifier.empty?
74
78
  end
75
-
79
+
76
80
  def expect_click!(location)
77
- control.should_receive(:click!).with(location).and_return(control)
81
+ expect(control).to receive(:click!).with(location).and_return(control)
78
82
  end
79
-
83
+
80
84
  def expect_click(location)
81
- control.should_receive(:click).with(location).and_return(control)
85
+ expect(control).to receive(:click).with(location).and_return(control)
82
86
  end
83
-
87
+
84
88
  def expect_click_menu_bar(menu_item, menu_name)
85
- control.should_receive(:click_menu_bar).with(menu_item, menu_name).and_return(control)
89
+ expect(control).to receive(:click_menu_bar).with(menu_item, menu_name).and_return(control)
86
90
  end
87
-
91
+
88
92
  def expect_get!(element, location)
89
- control.should_receive(:get!).with(element, location)
93
+ expect(control).to receive(:get!).with(element, location)
90
94
  end
91
-
95
+
92
96
  def expect_tell(do_this)
93
- control.should_receive(:tell).with(do_this)
97
+ expect(control).to receive(:tell).with(do_this)
94
98
  end
95
-
99
+
96
100
  def expect_system_event(event)
97
- control.should_receive(:system_event).with(event)
101
+ expect(control).to receive(:system_event).with(event)
98
102
  end
99
103
 
100
104
  def expect_system_event!(event)
101
- control.should_receive(:system_event!).with(event)
105
+ expect(control).to receive(:system_event!).with(event)
102
106
  end
103
-
107
+
104
108
  def expect_exists?(location)
105
- control.should_receive(:exists?).with(location)
109
+ expect(control).to receive(:exists?).with(location)
106
110
  end
107
-
111
+
108
112
  def expect_not_exists?(location)
109
- control.should_receive(:not_exists?).with(location)
113
+ expect(control).to receive(:not_exists?).with(location)
110
114
  end
111
-
115
+
112
116
  def expect_wait_until_exists(*location)
113
- control.should_receive(:wait_until_exists).with(*location)
117
+ expect(control).to receive(:wait_until_exists).with(*location)
114
118
  end
115
119
 
116
120
  def expect_wait_until_exists!(*location)
117
- control.should_receive(:wait_until_exists!).with(*location)
121
+ expect(control).to receive(:wait_until_exists!).with(*location)
118
122
  end
119
-
123
+
120
124
  def expect_wait_until_not_exists(location)
121
- control.should_receive(:wait_until_not_exists).with(location)
125
+ expect(control).to receive(:wait_until_not_exists).with(location)
122
126
  end
123
127
 
124
128
  def expect_wait_until_not_exists!(location, action)
125
- control.should_receive(:wait_until_not_exists!).with(location)
129
+ expect(control).to receive(:wait_until_not_exists!).with(location)
126
130
  end
127
-
131
+
128
132
  def expect_until_not_exists!(element)
129
- control.should_receive(:until_not_exists!).with(element).and_yield
130
- end
133
+ expect(control).to receive(:until_not_exists!).with(element).and_yield
134
+ end
131
135
  end
132
- end
136
+ end
data/lib/osaka/pages.rb CHANGED
@@ -1,9 +1,9 @@
1
1
 
2
2
  module Osaka
3
-
3
+
4
4
  class PagesError < RuntimeError
5
5
  end
6
-
6
+
7
7
  class PagesMailMergeDialog
8
8
  attr_accessor :control, :location
9
9
 
@@ -11,30 +11,30 @@ module Osaka
11
11
  @location = location
12
12
  @control = control
13
13
  end
14
-
14
+
15
15
  def merge
16
16
  control.click!(at.button("Merge").sheet(1))
17
17
  print_dialog_location = at.window("Print")
18
18
  control.wait_until_exists!(at.menu_button("PDF") + print_dialog_location)
19
19
  TypicalPrintDialog.new(control.name, print_dialog_location)
20
20
  end
21
-
21
+
22
22
  def set_merge_to_new_document
23
23
  set_merge_to_document_printer(1)
24
24
  end
25
-
25
+
26
26
  def set_merge_to_printer
27
27
  set_merge_to_document_printer(2)
28
28
  end
29
-
29
+
30
30
  private
31
31
  def set_merge_to_document_printer(value)
32
32
  control.click(at.pop_up_button(2).sheet(1))
33
33
  control.wait_until_exists!(at.menu_item(value).menu(1).pop_up_button(2).sheet(1))
34
34
  control.click!(at.menu_item(value).menu(1).pop_up_button(2).sheet(1))
35
- end
35
+ end
36
36
  end
37
-
37
+
38
38
  class PagesInspector
39
39
  attr_accessor :control
40
40
  attr_accessor :location_symbol_map
@@ -52,41 +52,50 @@ module Osaka
52
52
  @location_symbol_map[:chart] = 8
53
53
  @location_symbol_map[:link] = 9
54
54
  @location_symbol_map[:quicktime] = 10
55
- end
56
-
55
+ end
56
+
57
57
  def get_location_from_symbol(inspector_name)
58
58
  at.radio_button(@location_symbol_map[inspector_name]).radio_group(1)
59
59
  end
60
-
60
+
61
61
  def select_inspector(inspector)
62
62
  control.click(get_location_from_symbol(inspector))
63
63
  control.wait_until_exists(at.window(inspector.to_s))
64
64
  control.set_current_window(inspector.to_s)
65
65
  end
66
-
66
+
67
67
  def change_mail_merge_source
68
68
  select_inspector(:link)
69
69
  control.click(at.radio_button(3).tab_group(1).group(1)).wait_until_exists(at.button("Choose...").tab_group(1).group(1))
70
- control.click(at.button("Choose...").tab_group(1).group(1))
70
+ control.click(at.button("Choose...").tab_group(1).group(1))
71
71
  end
72
-
72
+
73
73
  end
74
74
 
75
75
  class Pages < TypicalApplication
76
-
76
+
77
77
  def initialize
78
78
  super "Pages"
79
79
  end
80
-
80
+
81
81
  def type(text)
82
82
  control.keystroke(text)
83
83
  end
84
-
84
+
85
85
  def self.create_document(filename, &block)
86
- numbers = Osaka::Pages.new
87
- numbers.create_document(filename, &block)
86
+ pages = Osaka::Pages.new
87
+ pages.create_document(filename, &block)
88
+ end
89
+
90
+ def new_document
91
+ super
92
+ if control.current_window_name == "Template Chooser"
93
+ control.set_current_window(do_and_wait_for_new_window {
94
+ control.click(at.button("Choose").window("Template Chooser"))
95
+ })
96
+ end
88
97
  end
89
-
98
+
90
99
  def set_mail_merge_document(filename)
91
100
  inspector.change_mail_merge_source
92
101
  control.wait_until_exists(at.sheet(1))
@@ -97,19 +106,19 @@ module Osaka
97
106
  if (control.exists?(at.sheet(1).sheet(1)))
98
107
  raise(PagesError, "Setting Mail Merge numbers file failed")
99
108
  end
100
- control.click(at.button("OK").sheet(1))
109
+ control.click(at.button("OK").sheet(1))
101
110
  end
102
-
111
+
103
112
  def mail_merge_field(field_name)
104
113
  control.click_menu_bar(at.menu_item(field_name).menu(1).menu_item("Merge Field"), "Insert")
105
114
  end
106
-
115
+
107
116
  def mail_merge
108
117
  control.click_menu_bar(at.menu_item(20), "Edit")
109
118
  control.wait_until_exists(at.button("Merge").sheet(1))
110
119
  PagesMailMergeDialog.new(at.sheet(1), control)
111
120
  end
112
-
121
+
113
122
  def mail_merge_to_pdf(filename)
114
123
  mail_merge_dialog = mail_merge
115
124
  mail_merge_dialog.set_merge_to_printer
@@ -128,6 +137,6 @@ module Osaka
128
137
  }
129
138
  PagesInspector.new(control.name, at.window(window_name))
130
139
  end
131
-
140
+
132
141
  end
133
- end
142
+ end