osaka 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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