osaka 0.4.1 → 0.4.2

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.
@@ -42,6 +42,10 @@ module Osaka
42
42
  create_location_with_added_name("group", name)
43
43
  end
44
44
 
45
+ def tab_group(name)
46
+ create_location_with_added_name("tab group", name)
47
+ end
48
+
45
49
  def window(name)
46
50
  create_location_with_added_name("window", name)
47
51
  end
@@ -110,6 +114,22 @@ module Osaka
110
114
  create_location_with_added_name("outline", name)
111
115
  end
112
116
 
117
+ def ui_element(name)
118
+ create_location_with_added_name("UI element", name)
119
+ end
120
+
121
+ def row(name)
122
+ create_location_with_added_name("row", name)
123
+ end
124
+
125
+ def radio_group(name)
126
+ create_location_with_added_name("radio group", name)
127
+ end
128
+
129
+ def radio_button(name)
130
+ create_location_with_added_name("radio button", name)
131
+ end
132
+
113
133
  def to_location_string(name)
114
134
  return name.to_s if name.kind_of? Integer
115
135
  '"' + name.to_s + '"'
data/lib/osaka/numbers.rb CHANGED
@@ -6,8 +6,24 @@ module Osaka
6
6
  super "Numbers"
7
7
  end
8
8
 
9
+ def new_document
10
+ super
11
+ control.set_current_window(do_and_wait_for_new_window {
12
+ control.keystroke(:return)
13
+ })
14
+ end
15
+
16
+ def self.create_document(filename)
17
+ numbers = Osaka::Numbers.new
18
+ numbers.new_document
19
+ yield numbers
20
+ numbers.save_as(filename)
21
+ numbers.close
22
+ end
23
+
9
24
  def fill_cell(column, row, value)
10
25
  control.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
26
  end
27
+
12
28
  end
13
29
  end
data/lib/osaka/pages.rb CHANGED
@@ -30,13 +30,70 @@ module Osaka
30
30
  control.click!(at.menu_item(value).menu(1).pop_up_button(2).sheet(1))
31
31
  end
32
32
  end
33
+
34
+ class PagesInspector
35
+ attr_accessor :control
36
+ attr_accessor :location_symbol_map
37
+
38
+ def initialize(application_name, own_location)
39
+ @control = Osaka::RemoteControl.new(application_name, own_location)
40
+ @location_symbol_map = {}
41
+ @location_symbol_map[:document] = 1
42
+ @location_symbol_map[:layout] = 2
43
+ @location_symbol_map[:wrap] = 3
44
+ @location_symbol_map[:text] = 4
45
+ @location_symbol_map[:graphic] = 5
46
+ @location_symbol_map[:metrics] = 6
47
+ @location_symbol_map[:table] = 7
48
+ @location_symbol_map[:chart] = 8
49
+ @location_symbol_map[:link] = 9
50
+ @location_symbol_map[:quicktime] = 10
51
+ end
52
+
53
+ def get_location_from_symbol(inspector_name)
54
+ at.radio_button(@location_symbol_map[inspector_name]).radio_group(1)
55
+ end
56
+
57
+ def select_inspector(inspector)
58
+ control.click(get_location_from_symbol(inspector))
59
+ control.wait_until_exists(at.window(inspector.to_s))
60
+ control.set_current_window(inspector.to_s)
61
+ end
62
+
63
+ def change_mail_merge_source
64
+ select_inspector(:link)
65
+ control.click(at.button("Choose...").tab_group(1).group(1))
66
+ end
67
+
68
+ end
33
69
 
34
70
  class Pages < TypicalApplication
35
71
 
36
72
  def initialize
37
73
  super "Pages"
38
74
  end
75
+
76
+ def type(text)
77
+ control.keystroke(text)
78
+ end
39
79
 
80
+ def set_mail_merge_document(filename)
81
+ inspector.change_mail_merge_source
82
+ control.wait_until_exists(at.sheet(1))
83
+ open_dialog = do_and_wait_for_new_window {
84
+ control.click(at.radio_button("Numbers Document:").radio_group(1).sheet(1))
85
+ }
86
+ dialog = create_dialog(TypicalOpenDialog, at.window(open_dialog))
87
+ dialog.set_folder(File.dirname(filename))
88
+ dialog.select_file(File.basename(filename))
89
+ control.click(at.button("OK").sheet(1))
90
+
91
+ end
92
+
93
+ def mail_merge_field(field_name)
94
+ control.click_menu_bar(at.menu_item(field_name).menu(1).menu_item("Merge Field"), "Insert")
95
+ end
96
+
40
97
  def mail_merge
41
98
  control.click_menu_bar(at.menu_item(20), "Edit")
42
99
  control.wait_until_exists(at.button("Merge").sheet(1))
@@ -49,6 +106,18 @@ module Osaka
49
106
  print_dialog = mail_merge_dialog.merge
50
107
  print_dialog.save_as_pdf(filename)
51
108
  end
109
+
110
+ def inspector
111
+ if !control.exists?(at.menu_item("Show Inspector").menu(1).menu_bar_item("View").menu_bar(1))
112
+ control.click_menu_bar(at.menu_item("Hide Inspector"), "View")
113
+ control.wait_until_exists(at.menu_item("Show Inspector").menu(1).menu_bar_item("View").menu_bar(1))
114
+ end
115
+
116
+ window_name = do_and_wait_for_new_window {
117
+ control.click_menu_bar(at.menu_item("Show Inspector"), "View")
118
+ }
119
+ PagesInspector.new(control.name, at.window(window_name))
120
+ end
52
121
 
53
122
  end
54
123
  end
@@ -190,6 +190,13 @@ module Osaka
190
190
  def get_app!(element)
191
191
  system_event!("get #{element}").strip
192
192
  end
193
+
194
+ def attributes(location = "")
195
+ attributelist = get!("attributes", location)
196
+ attributelist.split("of application process #{name}").collect { |attribute|
197
+ attribute_match = attribute.match("attribute (.+?) .*")[1]
198
+ }
199
+ end
193
200
 
194
201
  def set(element, location, value)
195
202
  activate
@@ -86,7 +86,7 @@ module Osaka
86
86
  exit
87
87
  return
88
88
  end
89
- raise(Osaka::ScriptRunnerError, "Error received while executing: #{applescript}")
89
+ raise(Osaka::ScriptRunnerError, "Error received while executing: \"#{applescript}\" with message \"#{ex.message}\"")
90
90
  end
91
91
  print_debug_info_for_additional_output(output)
92
92
  output
@@ -31,8 +31,10 @@ module Osaka
31
31
 
32
32
  def open (filename)
33
33
  abolutePathFileName = File.absolute_path(filename)
34
- control.tell("open \"#{abolutePathFileName}\"")
35
- control.set_current_window(File.basename(filename))
34
+ new_window = do_and_wait_for_new_window {
35
+ control.tell("open \"#{abolutePathFileName}\"")
36
+ }
37
+ control.set_current_window(new_window)
36
38
  end
37
39
 
38
40
  def wait_for_window_and_dialogs_to_close(option)
@@ -101,6 +103,12 @@ module Osaka
101
103
  new_instance
102
104
  end
103
105
 
106
+ def duplicate_and_close_original
107
+ new_instance = duplicate
108
+ close
109
+ @control = new_instance.control
110
+ end
111
+
104
112
  def save
105
113
  control.keystroke("s", :command)
106
114
  end
@@ -109,23 +117,24 @@ module Osaka
109
117
  control.exists?(at.menu_item("Save…").menu(1).menu_bar_item("File").menu_bar(1))
110
118
  end
111
119
 
112
- def save_dialog
120
+ def save_as(filename)
113
121
  if save_pops_up_dialog?
114
122
  save
115
- control.wait_until_exists(at.sheet(1))
116
123
  else
117
- control.keystroke("s", [:command, :shift]).wait_until_exists(at.sheet(1))
124
+ if duplicate_available?
125
+ duplicate_and_close_original
126
+ save
127
+ else
128
+ control.keystroke("s", [:command, :shift])
129
+ end
118
130
  end
119
- create_save_dialog(at.sheet(1) + control.base_location)
131
+
132
+ wait_for_save_dialog_and_save_file(filename)
120
133
  end
121
134
 
122
- def save_as(filename)
123
- if duplicate_available?
124
- new_instance = duplicate
125
- close
126
- @control = new_instance.control.clone
127
- end
128
- dialog = save_dialog
135
+ def wait_for_save_dialog_and_save_file(filename)
136
+ control.wait_until_exists(at.sheet(1))
137
+ dialog = create_dialog(TypicalSaveDialog, at.sheet(1))
129
138
  dialog.save(filename)
130
139
  control.set_current_window(File.basename(filename))
131
140
  end
@@ -166,18 +175,14 @@ module Osaka
166
175
  control.keystroke("a", :command)
167
176
  end
168
177
 
169
- def create_print_dialog(location)
170
- TypicalPrintDialog.new(control.name, location)
171
- end
172
-
173
- def create_save_dialog(location)
174
- TypicalSaveDialog.new(control.name, location)
175
- end
176
-
177
178
  def print_dialog
178
179
  control.keystroke("p", :command).wait_until_exists(at.sheet(1))
179
- create_print_dialog(at.sheet(1) + control.base_location)
180
+ create_dialog(TypicalPrintDialog, at.sheet(1))
180
181
  end
181
-
182
+
183
+ def create_dialog(dialog_class, location)
184
+ dialog_class.new(control.name, location + (location.has_top_level_element? ? "" : control.base_location))
185
+ end
186
+
182
187
  end
183
188
  end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+ module Osaka
3
+
4
+ class TypicalFinderDialog
5
+ attr_accessor :control
6
+
7
+ def initialize(application_name, own_location)
8
+ @control = Osaka::RemoteControl.new(application_name, own_location)
9
+ end
10
+
11
+ def set_folder(pathname)
12
+ return if pathname == "."
13
+
14
+ control.keystroke("g", [ :command, :shift ]).wait_until_exists(at.sheet(1))
15
+ control.set("value", at.text_field(1).sheet(1), pathname)
16
+ control.click(at.button("Go").sheet(1)).wait_until_not_exists(at.sheet(1))
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+ module Osaka
3
+
4
+ class OpenDialogCantSelectFile < StandardError
5
+ end
6
+
7
+ class TypicalOpenDialog < TypicalFinderDialog
8
+
9
+ def file_list_location
10
+ at.outline(1).scroll_area(2).splitter_group(1).group(1)
11
+ end
12
+
13
+ def text_field_location_from_row(row)
14
+ at.text_field(1).ui_element(1).row(row) + file_list_location
15
+ end
16
+
17
+ def static_field_location_from_row(row)
18
+ at.static_text(1).ui_element(1).row(row) + file_list_location
19
+ end
20
+
21
+ def greyed_out?(row)
22
+ !control.exists?(text_field_location_from_row(row))
23
+ end
24
+
25
+ def click_open
26
+ control.click(at.button("Open"))
27
+ end
28
+
29
+ def field_location_from_row(row)
30
+ if (greyed_out?(row))
31
+ static_field_location_from_row(row)
32
+ else
33
+ text_field_location_from_row(row)
34
+ end
35
+ end
36
+
37
+ def select_file_by_row(row)
38
+ raise(OpenDialogCantSelectFile, "Tried to select a file, but it either doesn't exist or is greyed out") if (greyed_out?(row))
39
+ control.set!("selected", at.row(1) + file_list_location, true)
40
+ end
41
+
42
+ def amount_of_files_in_list
43
+ amount_of_rows = control.get!("rows", file_list_location)
44
+ amount_match_data = amount_of_rows.match(/.*row (\d) of/)
45
+ amount_match_data.nil? ? 0 : amount_match_data[1].to_i
46
+ end
47
+
48
+ def filename_at(row)
49
+ control.get!("value", field_location_from_row(row))
50
+ end
51
+
52
+ def select_file(filename)
53
+ amount_of_files_in_list.times() { |row|
54
+ if filename_at(row+1) == filename
55
+ select_file_by_row(row+1)
56
+ click_open
57
+ end
58
+ }
59
+ end
60
+ end
61
+
62
+ end
@@ -1,30 +1,19 @@
1
1
  # encoding: utf-8
2
2
  module Osaka
3
-
4
- class TypicalSaveDialog
5
- attr_accessor :control
3
+
4
+ class TypicalSaveDialog < TypicalFinderDialog
6
5
 
7
- def initialize(application_name, own_location)
8
- @control = Osaka::RemoteControl.new(application_name, own_location)
6
+ def click_save
7
+ control.click(at.button("Save")).wait_until_not_exists(control.base_location)
9
8
  end
10
9
 
11
10
  def set_filename(filename)
12
11
  control.set("value", at.text_field(1), filename)
13
12
  end
14
-
15
- def set_folder(pathname)
16
- control.keystroke("g", [ :command, :shift ]).wait_until_exists(at.sheet(1))
17
- control.set("value", at.text_field(1).sheet(1), pathname)
18
- control.click(at.button("Go").sheet(1)).wait_until_not_exists(at.sheet(1))
19
- end
20
-
21
- def click_save
22
- control.click(at.button("Save")).wait_until_not_exists(control.base_location)
23
- end
24
-
13
+
25
14
  def save(filename)
15
+ set_folder(File.dirname(filename))
26
16
  set_filename(File.basename(filename))
27
- set_folder(File.dirname(filename)) unless File.dirname(filename) == "."
28
17
  click_save
29
18
  end
30
19
 
data/lib/osaka/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Osaka
3
- VERSION = "0.4.1"
3
+ VERSION = "0.4.2"
4
4
  end
data/lib/osaka.rb CHANGED
@@ -3,6 +3,8 @@ require 'osaka/scriptrunner'
3
3
  require 'osaka/location'
4
4
  require 'osaka/remotecontrol'
5
5
  require 'osaka/typicalapplication'
6
+ require 'osaka/typicalfinderdialog'
7
+ require 'osaka/typicalopendialog'
6
8
  require 'osaka/typicalsavedialog'
7
9
  require 'osaka/typicalprintdialog'
8
10
  require 'osaka/pages'
@@ -2,16 +2,38 @@ require 'tmpdir'
2
2
  require 'osaka'
3
3
 
4
4
  describe "Integration of mail merge flow with Pages and Numbers" do
5
+
6
+
7
+ before (:each) do
8
+ @tempdir = Dir.mktmpdir
9
+ @numbers_filename = File.join(@tempdir, "mail_merge_test.numbers")
10
+ @pages_template_filename = File.join(@tempdir, "mail_merge_template.pages")
11
+ @pdf_output_file = File.join(@tempdir, "output.pdf")
12
+ end
13
+
14
+ after (:each) do
15
+ FileUtils.remove_entry_secure @tempdir
16
+ end
5
17
 
6
18
  it "Should mail merge the assets and generate a PDF" do
7
-
8
- assets_directory = File.join(File.dirname(__FILE__), "assets")
9
- numbers_data = File.join(assets_directory, "mail_merge_data.numbers")
10
- pages_template = File.join(assets_directory, "mail_merge_template.pages")
11
- Dir.mktmpdir { |dir|
12
- pdf_output_file = File.join(dir, "output.pdf")
13
- CommonFlows::number_and_pages_mail_merge(numbers_data, pages_template, pdf_output_file)
14
- File.exists?(pdf_output_file).should == true
19
+
20
+ Osaka::Numbers.create_document (@numbers_filename) { |doc|
21
+ doc.fill_cell(2, 1, "Data")
22
+ doc.fill_cell(2, 2, "Hello World")
23
+ doc.fill_cell(2, 3, "of Data")
24
+ doc.fill_cell(2, 4, "in Numbers")
15
25
  }
26
+
27
+ pages = Osaka::Pages.new
28
+ pages.new_document
29
+ pages.set_mail_merge_document(@numbers_filename)
30
+
31
+ pages.type("Hello World! This is pages. We're going to mail merge!\r\r")
32
+ pages.mail_merge_field("Data");
33
+ pages.save_as(@pages_template_filename)
34
+ pages.close
35
+
36
+ CommonFlows::number_and_pages_mail_merge(@numbers_filename, @pages_template_filename, @pdf_output_file)
37
+ File.exists?(@pdf_output_file).should == true
16
38
  end
17
39
  end
data/spec/numbers_spec.rb CHANGED
@@ -13,4 +13,29 @@ describe "Osaka::Numbers" do
13
13
  subject.fill_cell(1, 2, "30")
14
14
  end
15
15
 
16
+ it "Should be able to select blank from the template choser" do
17
+ expect_set_current_window("Template Choser")
18
+ subject.should_receive(:do_and_wait_for_new_window).and_return("Template Choser")
19
+ expect_set_current_window("Untitled")
20
+ subject.should_receive(:do_and_wait_for_new_window).and_yield.and_return("Untitled")
21
+ expect_keystroke(:return)
22
+ subject.new_document
23
+ end
24
+
25
+ it "Should be able to easily create a document, put something, save it, and close it again" do
26
+
27
+ Osaka::Numbers.should_receive(:new).any_number_of_times.and_return(mock("Numbers"))
28
+ subject.should_receive(:new_document)
29
+ subject.should_receive(:method_call_from_code_block)
30
+ subject.should_receive(:save_as).with("filename")
31
+ subject.should_receive(:close)
32
+
33
+ Osaka::Numbers.create_document("filename") { |doc|
34
+ doc.method_call_from_code_block
35
+ }
36
+
37
+ end
38
+
39
+
40
+
16
41
  end
data/spec/pages_spec.rb CHANGED
@@ -7,7 +7,16 @@ describe "Osaka::Pages" do
7
7
 
8
8
  subject { Osaka::Pages.new }
9
9
 
10
- let (:control) { subject.control = mock("Remote Control").as_null_object}
10
+ let (:control) { subject.control = mock("Remote Control", :name => "ApplicationName")}
11
+
12
+ context "Basic document operations" do
13
+
14
+ it "Should be able to type in the file" do
15
+ expect_keystroke("Hello")
16
+ subject.type("Hello")
17
+ end
18
+
19
+ end
11
20
 
12
21
  it "Should be able to do mail merge to a PDF flow" do
13
22
 
@@ -31,10 +40,95 @@ describe "Osaka::Pages" do
31
40
 
32
41
  it "Should click the merge button of the mail merge dialog" do
33
42
  expect_current_window_name.any_number_of_times.and_return("Pages.pages")
43
+
44
+ expect_click_menu_bar(at.menu_item(20), "Edit")
45
+ expect_wait_until_exists(at.button("Merge").sheet(1))
46
+
34
47
  expect_click!(at.button("Merge").sheet(1))
35
48
  expect_wait_until_exists!(at.menu_button("PDF").window("Print"))
36
49
  subject.mail_merge.merge
37
50
  end
51
+
52
+ it "Should be able to get an inspector object" do
53
+ subject.should_receive(:do_and_wait_for_new_window).and_yield.and_return("Link")
54
+ expect_exists?(at.menu_item("Show Inspector").menu(1).menu_bar_item("View").menu_bar(1)).and_return(true)
55
+ expect_click_menu_bar(at.menu_item("Show Inspector"), "View")
56
+
57
+ inspector_mock = mock("Inspector")
58
+ Osaka::PagesInspector.should_receive(:new).with(control.name, at.window("Link")).and_return(inspector_mock)
59
+ subject.inspector.should equal(inspector_mock)
60
+ end
61
+
62
+ it "Should be able to get the inspector object also when it is already visible" do
63
+ subject.should_receive(:do_and_wait_for_new_window).and_yield.and_return("Link")
64
+ expect_exists?(at.menu_item("Show Inspector").menu(1).menu_bar_item("View").menu_bar(1)).and_return(false)
65
+ expect_click_menu_bar(at.menu_item("Hide Inspector"), "View")
66
+ expect_wait_until_exists(at.menu_item("Show Inspector").menu(1).menu_bar_item("View").menu_bar(1))
67
+ expect_click_menu_bar(at.menu_item("Show Inspector"), "View")
68
+ subject.inspector
69
+ end
70
+
71
+ it "Should be able to change the mail merge document source" do
72
+ inspector_mock = mock("Inspector")
73
+ subject.should_receive(:inspector).and_return(inspector_mock)
74
+ inspector_mock.should_receive(:change_mail_merge_source)
75
+
76
+ expect_wait_until_exists(at.sheet(1))
77
+ subject.should_receive(:do_and_wait_for_new_window).and_yield.and_return("dialog")
78
+ expect_click(at.radio_button("Numbers Document:").radio_group(1).sheet(1))
79
+
80
+ dialog_mock = mock("Open Dialog")
81
+ subject.should_receive(:create_dialog).with(Osaka::TypicalOpenDialog, at.window("dialog")).and_return(dialog_mock)
82
+ dialog_mock.should_receive(:set_folder).with("/tmp")
83
+ dialog_mock.should_receive(:select_file).with("filename")
84
+ expect_click(at.button("OK").sheet(1))
85
+
86
+ subject.set_mail_merge_document("/tmp/filename")
87
+ end
88
+
89
+ it "Should be able to insert a merge field" do
90
+ expect_click_menu_bar(at.menu_item("Data").menu(1).menu_item("Merge Field"), "Insert")
91
+ subject.mail_merge_field("Data")
92
+ end
93
+
94
+
95
+ end
96
+
97
+ describe "Osaka::Pages Inspector" do
98
+
99
+ include(*Osaka::OsakaExpectations)
100
+
101
+ subject {Osaka::PagesInspector.new("Pages", "Link")}
102
+ let(:control) {subject.control = mock("RemoteControl")}
103
+
104
+ it "Can convert symbolic names to locations" do
105
+ # Nice... checking a map. Perhaps delete ?
106
+ subject.get_location_from_symbol(:document).should == at.radio_button(1).radio_group(1)
107
+ subject.get_location_from_symbol(:layout).should == at.radio_button(2).radio_group(1)
108
+ subject.get_location_from_symbol(:wrap).should == at.radio_button(3).radio_group(1)
109
+ subject.get_location_from_symbol(:text).should == at.radio_button(4).radio_group(1)
110
+ subject.get_location_from_symbol(:graphic).should == at.radio_button(5).radio_group(1)
111
+ subject.get_location_from_symbol(:metrics).should == at.radio_button(6).radio_group(1)
112
+ subject.get_location_from_symbol(:table).should == at.radio_button(7).radio_group(1)
113
+ subject.get_location_from_symbol(:chart).should == at.radio_button(8).radio_group(1)
114
+ subject.get_location_from_symbol(:link).should == at.radio_button(9).radio_group(1)
115
+ subject.get_location_from_symbol(:quicktime).should == at.radio_button(10).radio_group(1)
116
+ end
117
+
118
+
119
+ it "Should be able to select the different inspectors" do
120
+ expect_click(subject.get_location_from_symbol(:document))
121
+ expect_wait_until_exists(at.window("document"))
122
+ expect_set_current_window("document")
123
+ subject.select_inspector(:document)
124
+ end
125
+
126
+ it "Change the mail merge source" do
127
+ subject.should_receive(:select_inspector).with(:link)
128
+ expect_click(at.button("Choose...").tab_group(1).group(1))
129
+ subject.change_mail_merge_source
130
+ end
131
+
38
132
  end
39
133
 
40
134
  describe "Osaka::Pages Mail Merge dialog" do
@@ -181,7 +181,7 @@ describe "Osaka::RemoteControl" do
181
181
 
182
182
  it "Should print a proper error message when it times out while waiting for something" do
183
183
  Timeout.should_receive(:timeout).with(5).and_raise(Timeout::Error.new)
184
- lambda { subject.until_exists!(at.window(1)) }.should raise_error(Osaka::TimeoutError, "Timed out while waiting for: [window 1]")
184
+ expect { subject.until_exists!(at.window(1)) }.to raise_error(Osaka::TimeoutError, "Timed out while waiting for: [window 1]")
185
185
  end
186
186
  end
187
187
 
@@ -344,6 +344,16 @@ describe "Osaka::RemoteControl" do
344
344
  subject.window_list.should == ["one"]
345
345
  end
346
346
 
347
+ it "Should be able to get the attributes of a window and parse the result" do
348
+ 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)).should == ["AXRole", "AXRoleDescription", "AXSubrole"]
350
+ end
351
+
352
+ it "Should be able to get the attributes of the application too" do
353
+ 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)).should == ["AXRole", "AXRoleDescription"]
355
+ end
356
+
347
357
  end
348
358
 
349
359
  describe "Dealing with base locations and window lists" do
@@ -61,8 +61,8 @@ describe "Osaka::ScriptRunner" do
61
61
  end
62
62
 
63
63
  it "Should raise an exception witha proper error message when the applescript fails" do
64
- subject.should_receive(:do_system).and_raise(Osaka::SystemCommandFailed)
65
- lambda {subject.execute("Fuck off!")}.should raise_error(Osaka::ScriptRunnerError, "Error received while executing: Fuck off!")
64
+ subject.should_receive(:do_system).and_raise(Osaka::SystemCommandFailed.new("Message"))
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
@@ -7,7 +7,7 @@ describe "Osaka::TypicalApplication" do
7
7
 
8
8
  subject { Osaka::TypicalApplication.new("ApplicationName") }
9
9
 
10
- let(:control) { subject.control = mock("RemoteControl", :name => "ApplicationName", :base_location => "", :mac_version => :mountain_lion) }
10
+ let(:control) { subject.control = mock("RemoteControl", :name => "ApplicationName", :base_location => "base", :mac_version => :mountain_lion) }
11
11
 
12
12
  before (:each) do
13
13
  Osaka::ScriptRunner.enable_debug_prints
@@ -41,20 +41,22 @@ describe "Osaka::TypicalApplication" do
41
41
  subject.control.current_window_name.should == "Original"
42
42
  end
43
43
 
44
+ end
45
+
46
+ context "Opening and new document" do
47
+
44
48
  it "Should pass the right open string to the application osascript" do
45
49
  filename = "filename.key"
46
50
  expect_tell("open \"#{File.absolute_path(filename)}\"")
51
+ subject.stub(:do_and_wait_for_new_window).and_yield.and_return(filename)
47
52
  expect_set_current_window(filename)
48
53
  subject.open(filename)
49
54
  end
50
- end
51
-
52
- context "Opening and new document" do
53
-
55
+
54
56
  it "Should only get the basename of the filename when it sets the window title." do
55
57
  filename = "/root/dirname/filename.key"
56
- expect_tell("open \"#{File.absolute_path(filename)}\"")
57
- expect_set_current_window("filename.key")
58
+ subject.should_receive(:do_and_wait_for_new_window).and_return("filename")
59
+ expect_set_current_window("filename")
58
60
  subject.open(filename)
59
61
  end
60
62
 
@@ -116,29 +118,50 @@ describe "Osaka::TypicalApplication" do
116
118
  expect_keystroke("s", :command)
117
119
  subject.save
118
120
  end
119
-
121
+
120
122
  it "Should be able to save as a file without duplicate being available" do
123
+ subject.should_receive(:save_pops_up_dialog?).and_return(false)
121
124
  subject.should_receive(:duplicate_available?).and_return(false)
122
125
 
123
- subject.should_receive(:save_dialog).and_return(save_dialog)
124
- save_dialog.should_receive(:save).with("filename")
125
- expect_set_current_window("filename")
126
+ expect_keystroke("s", [:command, :shift])
127
+ subject.should_receive(:wait_for_save_dialog_and_save_file).with("filename")
126
128
 
127
129
  subject.save_as("filename")
128
130
  end
129
131
 
130
132
  it "Should be able to save as a file using the duplicate..." do
133
+ subject.should_receive(:save_pops_up_dialog?).and_return(false)
131
134
  subject.should_receive(:duplicate_available?).and_return(true)
132
135
 
133
- subject.stub_chain(:duplicate, :control, :clone).and_return(new_instance_control)
134
- subject.should_receive(:close)
135
- subject.stub_chain(:save_dialog, :save)
136
- new_instance_control.should_receive(:set_current_window).with("filename")
137
-
136
+ subject.should_receive(:duplicate_and_close_original)
137
+ subject.should_receive(:save)
138
+ subject.should_receive(:wait_for_save_dialog_and_save_file).with("filename")
138
139
  subject.save_as("filename")
139
- subject.control.should equal(new_instance_control)
140
140
  end
141
-
141
+
142
+ it "Should be able to use normal Save when that pops up a dialog instead of save_as" do
143
+ subject.should_receive(:save_pops_up_dialog?).and_return(true)
144
+ subject.should_receive(:save)
145
+ subject.should_receive(:wait_for_save_dialog_and_save_file).with("filename")
146
+ subject.save_as("filename")
147
+ end
148
+
149
+ it "Should be able to wait for a save dialog and save the file" do
150
+ expect_wait_until_exists(at.sheet(1))
151
+ subject.should_receive(:create_dialog).with(Osaka::TypicalSaveDialog, at.sheet(1)).and_return(save_dialog)
152
+ save_dialog.should_receive(:save).with("/tmp/filename")
153
+ expect_set_current_window("filename")
154
+ subject.wait_for_save_dialog_and_save_file("/tmp/filename")
155
+ end
156
+
157
+
158
+ it "Should be able to duplicate and close the original document" do
159
+ subject.stub_chain(:duplicate, :control).and_return(new_instance_control)
160
+ subject.should_receive(:close)
161
+ subject.duplicate_and_close_original
162
+ subject.control.should equal(new_instance_control)
163
+ end
164
+
142
165
  it "Should be able to check whether Duplicate is supported" do
143
166
  expect_exists?(at.menu_item("Duplicate").menu(1).menu_bar_item("File").menu_bar(1)).and_return(true)
144
167
  subject.duplicate_available?.should == true
@@ -146,7 +169,7 @@ describe "Osaka::TypicalApplication" do
146
169
 
147
170
  it "Should throw an exception when duplicate is not available"do
148
171
  subject.should_receive(:duplicate_available?).and_return(false)
149
- lambda {subject.duplicate}.should raise_error(Osaka::VersioningError, "MacOS Versioning Error: Duplicate is not available on this Mac version")
172
+ expect {subject.duplicate}.to raise_error(Osaka::VersioningError, "MacOS Versioning Error: Duplicate is not available on this Mac version")
150
173
  end
151
174
 
152
175
  it "Should return a new keynote instance variable after duplication (Lion!)" do
@@ -177,20 +200,6 @@ describe "Osaka::TypicalApplication" do
177
200
  expect_exists?(at.menu_item("Save…").menu(1).menu_bar_item("File").menu_bar(1)).and_return(true)
178
201
  subject.save_pops_up_dialog?.should == true
179
202
  end
180
-
181
- it "Should be able to retrieve a save dialog by using save as" do
182
- subject.should_receive(:save_pops_up_dialog?).and_return(false)
183
- expect_keystroke("s", [:command, :shift])
184
- expect_wait_until_exists(at.sheet(1))
185
- subject.save_dialog
186
- end
187
-
188
- it "Should be able to retrieve a save dialog using duplicate and save" do
189
- subject.should_receive(:save_pops_up_dialog?).and_return(true)
190
- subject.should_receive(:save)
191
- expect_wait_until_exists(at.sheet(1))
192
- subject.save_dialog
193
- end
194
203
 
195
204
  end
196
205
 
@@ -247,7 +256,7 @@ describe "Osaka::TypicalApplication" do
247
256
  end
248
257
  end
249
258
 
250
- describe "Application info" do
259
+ context "Application info" do
251
260
  it "Should be able to retrieve an application info object and parse it" do
252
261
  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"}')
253
262
  app_info = subject.get_info
@@ -255,4 +264,17 @@ describe "Osaka::TypicalApplication" do
255
264
  end
256
265
  end
257
266
 
267
+ context "Simple Application helpers to create objects" do
268
+ it "Should be able to create dialogs with a helper" do
269
+ Osaka::TypicalSaveDialog.should_receive(:new).with(control.name, at.sheet(1) + control.base_location)
270
+ subject.create_dialog(Osaka::TypicalSaveDialog, at.sheet(1))
271
+ end
272
+
273
+ it "Should be able to create top level dialogs also with the helper" do
274
+ Osaka::TypicalSaveDialog.should_receive(:new).with(control.name, at.window("toplevel"))
275
+ subject.create_dialog(Osaka::TypicalSaveDialog, at.window("toplevel"))
276
+ end
277
+ end
278
+
279
+
258
280
  end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require 'osaka'
3
+
4
+ describe "Osaka::TypicalFinderDialog" do
5
+
6
+ include(*Osaka::OsakaExpectations)
7
+ subject { Osaka::TypicalFinderDialog.new("Application", at.window(1))}
8
+ let(:control) { subject.control = mock("RemoteControl", :base_location => at.window(1)) }
9
+
10
+
11
+ it "Should be able to set the path" do
12
+ expect_keystroke("g", [ :command, :shift ])
13
+ expect_wait_until_exists(at.sheet(1))
14
+ expect_set("value", at.text_field(1).sheet(1), "path")
15
+ expect_click(at.button("Go").sheet(1))
16
+ expect_wait_until_not_exists(at.sheet(1))
17
+ subject.set_folder("path")
18
+ end
19
+
20
+ it "Won't change the path when the path is the current one" do
21
+ control.should_not_receive(:keystroke)
22
+ subject.set_folder(".")
23
+ end
24
+
25
+ end
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+ require 'osaka'
3
+
4
+ describe "Osaka::TypicalOpenDialog" do
5
+
6
+ include(*Osaka::OsakaExpectations)
7
+ subject { Osaka::TypicalOpenDialog.new("Application", at.window(1))}
8
+ let(:control) { subject.control = mock("RemoteControl", :base_location => at.window(1)) }
9
+
10
+
11
+ it "Should be do nothing when the amount of files in the directory is 0" do
12
+ subject.should_receive(:amount_of_files_in_list).and_return(0)
13
+ subject.select_file("filename")
14
+ end
15
+
16
+ it "Should be able to select a file from Row 1" do
17
+ subject.should_receive(:amount_of_files_in_list).and_return(1)
18
+ subject.should_receive(:filename_at).with(1).and_return("filename")
19
+ subject.should_receive(:select_file_by_row).with(1)
20
+ subject.should_receive(:click_open)
21
+
22
+ subject.select_file("filename")
23
+ end
24
+
25
+ it "Should be able to select a file from Row 3" do
26
+ subject.should_receive(:amount_of_files_in_list).and_return(3)
27
+ subject.should_receive(:filename_at).and_return("filename", "filename2", "filename3")
28
+ subject.should_receive(:select_file_by_row).with(3)
29
+ subject.should_receive(:click_open)
30
+
31
+ subject.select_file("filename3")
32
+ end
33
+
34
+ it "Should be able to click open" do
35
+ expect_click(at.button("Open"))
36
+ subject.click_open
37
+ end
38
+
39
+
40
+ it "Should be able to get the name of a file from a row" do
41
+ subject.should_receive(:field_location_from_row).and_return(at.window("Location"))
42
+ expect_get!("value", at.window("Location")).and_return("filename")
43
+ subject.filename_at(1).should == "filename"
44
+ end
45
+
46
+ it "Should be able to select the filename (when that is possible)" do
47
+ subject.should_receive(:greyed_out?).and_return(false)
48
+ expect_set!("selected", at.row(1) + subject.file_list_location, true)
49
+ subject.select_file_by_row(1)
50
+ end
51
+
52
+ it "Should throw an exception when the filename that we want to select is greyed out" do
53
+ subject.should_receive(:greyed_out?).and_return(true)
54
+ expect { subject.select_file_by_row(1)}.to raise_error(Osaka::OpenDialogCantSelectFile, "Tried to select a file, but it either doesn't exist or is greyed out")
55
+ end
56
+
57
+ it "Should be able to get the amount of files in the current file list" do
58
+ expect_get!("rows", subject.file_list_location).and_return("row 1 of outline 1 of scroll area 2 of splitter group 1 of group 1 of window Open of application process Pages")
59
+ subject.amount_of_files_in_list.should == 1
60
+ end
61
+
62
+ it "Should be able to get the amount of files in the current file list with 2 files." do
63
+ expect_get!("rows", subject.file_list_location).and_return("row 1 of outline 1 of scroll area 2 of splitter group 1 of group 1 of window Open of application process Pages, row 2 of outline 1 of scroll area 2 of splitter group 1 of group 1 of window Open of application process Pages")
64
+ subject.amount_of_files_in_list.should == 2
65
+ end
66
+
67
+ it "Should be able to get the amount of files in the current file list when there are no files..." do
68
+ expect_get!("rows", subject.file_list_location).and_return("")
69
+ subject.amount_of_files_in_list.should == 0
70
+ end
71
+
72
+ it "Should be able to convert a row into a location when it is a text field" do
73
+ expect_exists?(subject.text_field_location_from_row(1)).and_return(true)
74
+ subject.field_location_from_row(1).should == subject.text_field_location_from_row(1)
75
+ end
76
+
77
+ it "Should be able to convert a row into a location when it is a static field." do
78
+ expect_exists?(subject.text_field_location_from_row(1)).and_return(false)
79
+ subject.field_location_from_row(1).should == subject.static_field_location_from_row(1)
80
+ end
81
+
82
+ it "Should be able to get the location of the list" do
83
+ subject.file_list_location.should == at.outline(1).scroll_area(2).splitter_group(1).group(1)
84
+ end
85
+ end
@@ -10,7 +10,6 @@ describe "Osaka::TypicalSaveDialog" do
10
10
  it "Should set the filename in the test field" do
11
11
  subject.should_receive(:set_filename).with("filename")
12
12
  subject.should_receive(:click_save)
13
- subject.should_not_receive(:set_folder)
14
13
  subject.save("filename")
15
14
  end
16
15
 
@@ -39,13 +38,5 @@ describe "Osaka::TypicalSaveDialog" do
39
38
  subject.set_filename("filename")
40
39
  end
41
40
 
42
- it "Should be able to set the path" do
43
- expect_keystroke("g", [ :command, :shift ])
44
- expect_wait_until_exists(at.sheet(1))
45
- expect_set("value", at.text_field(1).sheet(1), "path")
46
- expect_click(at.button("Go").sheet(1))
47
- expect_wait_until_not_exists(at.sheet(1))
48
- subject.set_folder("path")
49
- end
50
41
 
51
42
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: osaka
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.4.1
5
+ version: 0.4.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Bas Vodde
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-08-22 00:00:00 +08:00
13
+ date: 2012-11-17 00:00:00 +08:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -59,6 +59,8 @@ files:
59
59
  - lib/osaka/scriptrunner.rb
60
60
  - lib/osaka/textedit.rb
61
61
  - lib/osaka/typicalapplication.rb
62
+ - lib/osaka/typicalfinderdialog.rb
63
+ - lib/osaka/typicalopendialog.rb
62
64
  - lib/osaka/typicalprintdialog.rb
63
65
  - lib/osaka/typicalsavedialog.rb
64
66
  - lib/osaka/version.rb
@@ -66,8 +68,6 @@ files:
66
68
  - spec/assets/01_first_slides.key
67
69
  - spec/assets/02_second_slides.key
68
70
  - spec/assets/03_third_slides.key
69
- - spec/assets/mail_merge_data.numbers
70
- - spec/assets/mail_merge_template.pages
71
71
  - spec/calculator_spec.rb
72
72
  - spec/integration_calculator_spec.rb
73
73
  - spec/integration_keynote_spec.rb
@@ -84,6 +84,8 @@ files:
84
84
  - spec/scriptrunner_spec.rb
85
85
  - spec/textedit_spec.rb
86
86
  - spec/typicalapplication_spec.rb
87
+ - spec/typicalfinderdialog_spec.rb
88
+ - spec/typicalopendialog_spec.rb
87
89
  - spec/typicalprintdialog_spec.rb
88
90
  - spec/typicalsavedialog_spec.rb
89
91
  has_rdoc: true
Binary file
Binary file