osaka 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/osaka/location.rb +20 -0
- data/lib/osaka/numbers.rb +16 -0
- data/lib/osaka/pages.rb +69 -0
- data/lib/osaka/remotecontrol.rb +7 -0
- data/lib/osaka/scriptrunner.rb +1 -1
- data/lib/osaka/typicalapplication.rb +28 -23
- data/lib/osaka/typicalfinderdialog.rb +20 -0
- data/lib/osaka/typicalopendialog.rb +62 -0
- data/lib/osaka/typicalsavedialog.rb +6 -17
- data/lib/osaka/version.rb +1 -1
- data/lib/osaka.rb +2 -0
- data/spec/integration_pages_numbers_mail_merge_spec.rb +30 -8
- data/spec/numbers_spec.rb +25 -0
- data/spec/pages_spec.rb +95 -1
- data/spec/remotecontrol_spec.rb +11 -1
- data/spec/scriptrunner_spec.rb +2 -2
- data/spec/typicalapplication_spec.rb +56 -34
- data/spec/typicalfinderdialog_spec.rb +25 -0
- data/spec/typicalopendialog_spec.rb +85 -0
- data/spec/typicalsavedialog_spec.rb +0 -9
- metadata +6 -4
- data/spec/assets/mail_merge_data.numbers +0 -0
- data/spec/assets/mail_merge_template.pages +0 -0
data/lib/osaka/location.rb
CHANGED
@@ -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
|
data/lib/osaka/remotecontrol.rb
CHANGED
@@ -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
|
data/lib/osaka/scriptrunner.rb
CHANGED
@@ -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
|
-
|
35
|
-
|
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
|
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
|
-
|
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
|
-
|
131
|
+
|
132
|
+
wait_for_save_dialog_and_save_file(filename)
|
120
133
|
end
|
121
134
|
|
122
|
-
def
|
123
|
-
|
124
|
-
|
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
|
-
|
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
|
8
|
-
|
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
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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")
|
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
|
data/spec/remotecontrol_spec.rb
CHANGED
@@ -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
|
-
|
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
|
data/spec/scriptrunner_spec.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
57
|
-
expect_set_current_window("filename
|
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
|
-
|
124
|
-
|
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.
|
134
|
-
subject.should_receive(:
|
135
|
-
subject.
|
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
|
-
|
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
|
-
|
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.
|
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-
|
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
|