AXElements 0.9.0 → 1.0.0.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.yardopts +0 -4
- data/README.markdown +22 -17
- data/Rakefile +1 -1
- data/ext/accessibility/key_coder/extconf.rb +1 -1
- data/ext/accessibility/key_coder/key_coder.c +2 -4
- data/lib/accessibility.rb +3 -3
- data/lib/accessibility/core.rb +948 -0
- data/lib/accessibility/dsl.rb +30 -186
- data/lib/accessibility/enumerators.rb +1 -0
- data/lib/accessibility/factory.rb +78 -134
- data/lib/accessibility/graph.rb +5 -9
- data/lib/accessibility/highlighter.rb +86 -0
- data/lib/accessibility/{pretty_printer.rb → pp_inspector.rb} +4 -3
- data/lib/accessibility/qualifier.rb +3 -5
- data/lib/accessibility/screen_recorder.rb +217 -0
- data/lib/accessibility/statistics.rb +57 -0
- data/lib/accessibility/translator.rb +23 -32
- data/lib/accessibility/version.rb +2 -22
- data/lib/ax/application.rb +20 -159
- data/lib/ax/element.rb +42 -32
- data/lib/ax/scroll_area.rb +5 -6
- data/lib/ax/systemwide.rb +1 -33
- data/lib/ax_elements.rb +1 -9
- data/lib/ax_elements/core_graphics_workaround.rb +5 -0
- data/lib/ax_elements/nsarray_compat.rb +17 -97
- data/lib/ax_elements/vendor/inflection_data.rb +66 -0
- data/lib/ax_elements/vendor/inflections.rb +176 -0
- data/lib/ax_elements/vendor/inflector.rb +306 -0
- data/lib/minitest/ax_elements.rb +180 -0
- data/lib/mouse.rb +227 -0
- data/lib/rspec/expectations/ax_elements.rb +234 -0
- data/rakelib/gem.rake +3 -12
- data/rakelib/test.rake +15 -0
- data/test/helper.rb +20 -10
- data/test/integration/accessibility/test_core.rb +18 -0
- data/test/integration/accessibility/test_dsl.rb +40 -38
- data/test/integration/accessibility/test_enumerators.rb +1 -0
- data/test/integration/accessibility/test_graph.rb +0 -1
- data/test/integration/accessibility/test_qualifier.rb +2 -2
- data/test/integration/ax/test_application.rb +2 -9
- data/test/integration/ax/test_element.rb +0 -40
- data/test/integration/minitest/test_ax_elements.rb +89 -0
- data/test/integration/rspec/expectations/test_ax_elements.rb +102 -0
- data/test/sanity/accessibility/test_factory.rb +2 -2
- data/test/sanity/accessibility/test_highlighter.rb +56 -0
- data/test/sanity/accessibility/{test_pretty_printer.rb → test_pp_inspector.rb} +9 -9
- data/test/sanity/accessibility/test_statistics.rb +57 -0
- data/test/sanity/ax/test_application.rb +1 -16
- data/test/sanity/ax/test_element.rb +2 -2
- data/test/sanity/ax_elements/test_nsobject_inspect.rb +2 -4
- data/test/sanity/minitest/test_ax_elements.rb +17 -0
- data/test/sanity/rspec/expectations/test_ax_elements.rb +15 -0
- data/test/sanity/test_mouse.rb +22 -0
- data/test/test_core.rb +454 -0
- metadata +44 -69
- data/History.markdown +0 -41
- data/lib/accessibility/system_info.rb +0 -230
- data/lib/ax_elements/active_support_selections.rb +0 -10
- data/lib/ax_elements/mri.rb +0 -57
- data/test/sanity/accessibility/test_version.rb +0 -15
data/rakelib/gem.rake
CHANGED
@@ -4,24 +4,15 @@ ax_elements = Gem::Specification.load('AXElements.gemspec')
|
|
4
4
|
Gem::PackageTask.new(ax_elements) { }
|
5
5
|
|
6
6
|
desc 'Build and install gem (not including deps)'
|
7
|
-
task :install =>
|
7
|
+
task :install => :gem do
|
8
8
|
require 'rubygems/installer'
|
9
9
|
Gem::Installer.new("pkg/#{ax_elements.file_name}").install
|
10
10
|
end
|
11
11
|
|
12
|
-
desc 'Install dependencies for running AXElements'
|
13
|
-
task :setup do
|
14
|
-
require 'rubygems/dependency_installer'
|
15
|
-
ax_elements.runtime_dependencies.each do |dep|
|
16
|
-
puts "Installing #{dep.name} (#{dep.requirement})"
|
17
|
-
Gem::DependencyInstaller.new.install(dep.name, dep.requirement)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
12
|
desc 'Install dependencies for development'
|
22
|
-
task :setup_dev
|
13
|
+
task :setup_dev do
|
23
14
|
require 'rubygems/dependency_installer'
|
24
|
-
|
15
|
+
ax_elements.development_dependencies.each do |dep|
|
25
16
|
puts "Installing #{dep.name} (#{dep.requirement})"
|
26
17
|
Gem::DependencyInstaller.new.install(dep.name, dep.requirement)
|
27
18
|
end
|
data/rakelib/test.rake
CHANGED
@@ -23,6 +23,12 @@ task :clobber => :clobber_fixture
|
|
23
23
|
|
24
24
|
require 'rake/testtask'
|
25
25
|
namespace :test do
|
26
|
+
Rake::TestTask.new(:core) do |t|
|
27
|
+
t.libs << '.'
|
28
|
+
t.pattern = 'test/test_core.rb'
|
29
|
+
end
|
30
|
+
task :core => [:ext, :fixture]
|
31
|
+
|
26
32
|
Rake::TestTask.new(:sanity) do |t|
|
27
33
|
t.libs << '.'
|
28
34
|
t.pattern = "test/sanity/**/test_*.rb"
|
@@ -41,4 +47,13 @@ namespace :test do
|
|
41
47
|
t.pattern = "test/sanity/accessibility/test_string.rb"
|
42
48
|
end
|
43
49
|
task :string => :ext
|
50
|
+
|
51
|
+
desc 'Run tests under CRuby (where applicable)'
|
52
|
+
task :cruby do
|
53
|
+
if ENV['RUBY_VERSION'] # using rvm
|
54
|
+
puts sh 'rvm 1.9.3 do rake test:string'
|
55
|
+
else
|
56
|
+
sh 'rake test:string'
|
57
|
+
end
|
58
|
+
end
|
44
59
|
end
|
data/test/helper.rb
CHANGED
@@ -1,18 +1,28 @@
|
|
1
|
-
|
2
|
-
require 'accessibility/core'
|
3
|
-
framework 'Cocoa' if on_macruby?
|
1
|
+
framework 'Cocoa'
|
4
2
|
|
5
3
|
# We want to launch the test app and make sure it responds to
|
6
4
|
# accessibility queries, but that is difficult to know at what
|
7
5
|
# point it will start to respond, so we just sleep
|
8
|
-
|
6
|
+
APP_BUNDLE_URL = NSURL.fileURLWithPath File.expand_path './test/fixture/Release/AXElementsTester.app'
|
9
7
|
APP_BUNDLE_IDENTIFIER = 'com.marketcircle.AXElementsTester'
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
error = Pointer.new :id
|
10
|
+
TEST_APP = NSWorkspace.sharedWorkspace.launchApplicationAtURL APP_BUNDLE_URL,
|
11
|
+
options: NSWorkspaceLaunchAsync,
|
12
|
+
configuration: {},
|
13
|
+
error: error
|
14
|
+
if TEST_APP.nil?
|
15
|
+
$stderr.puts 'You need to build AND run the fixture app once before running tests'
|
16
|
+
$stderr.puts 'Run `rake run_fixture` to initalize the fixture'
|
17
|
+
exit 3
|
18
|
+
else
|
19
|
+
sleep 2 # Instead of using high level features of AXElements that we are
|
20
|
+
# testing, I think it is just safer to sleep
|
21
|
+
# Make sure the test app is closed when testing finishes
|
22
|
+
at_exit do
|
23
|
+
TEST_APP.terminate
|
24
|
+
puts STATS.to_s
|
25
|
+
end
|
16
26
|
end
|
17
27
|
|
18
28
|
|
@@ -22,5 +32,5 @@ require 'test/runner'
|
|
22
32
|
class MiniTest::Unit::TestCase
|
23
33
|
# needs to be defined in the class, there is a TOPLEVEL::PID
|
24
34
|
PID = pid_for APP_BUNDLE_IDENTIFIER
|
25
|
-
REF =
|
35
|
+
REF = AXUIElementCreateApplication(PID)
|
26
36
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test/integration/helper'
|
2
|
+
|
3
|
+
class TestAccessibilityCore < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
# this assumes that radar://10040865 is not fixed
|
6
|
+
# once it is fixed, this case becomes less of an
|
7
|
+
# issue anyways
|
8
|
+
def test_nil_children_returns_empty_array
|
9
|
+
app = app_with_name 'AXElementsTester'
|
10
|
+
menu = app.menu_bar_item(title: 'Help')
|
11
|
+
press menu
|
12
|
+
|
13
|
+
assert_empty menu.search_field.children
|
14
|
+
ensure
|
15
|
+
cancel menu if menu
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -166,8 +166,7 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
|
|
166
166
|
|
167
167
|
def test_wait_for_invalidation_of_element
|
168
168
|
app.main_window.button(title: 'Yes').perform(:press)
|
169
|
-
|
170
|
-
sleep 1
|
169
|
+
Dispatch::Queue.new("herp").after(1) do
|
171
170
|
app.main_window.button(title: 'No').perform(:press)
|
172
171
|
end
|
173
172
|
|
@@ -176,8 +175,7 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
|
|
176
175
|
|
177
176
|
def test_wait_for_invalidation_of_wait_for
|
178
177
|
app.main_window.button(title: 'Yes').perform(:press)
|
179
|
-
|
180
|
-
sleep 1
|
178
|
+
Dispatch::Queue.new("herp").after(1) do
|
181
179
|
app.main_window.button(title: 'No').perform(:press)
|
182
180
|
end
|
183
181
|
|
@@ -201,33 +199,48 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
|
|
201
199
|
app.main_window.set :position, orig_window_position if orig_window_position
|
202
200
|
end
|
203
201
|
|
204
|
-
def test_right_click_with_block
|
205
|
-
area = app.main_window.web_area
|
206
|
-
|
207
|
-
got_called = false
|
208
|
-
dsl.right_click area do
|
209
|
-
got_called = true
|
210
|
-
end
|
211
|
-
assert got_called
|
212
|
-
ensure
|
213
|
-
dsl.click area
|
214
|
-
end
|
215
|
-
|
216
|
-
def test_triple_click
|
217
|
-
dummy_text = 'Lorem ipsum dolor.' * 15
|
218
|
-
text_area.set :value, dummy_text
|
219
|
-
dsl.triple_click text_area
|
220
|
-
assert_equal dummy_text, text_area.selected_text
|
221
|
-
ensure
|
222
|
-
app.main_window.text_area.set :value, ''
|
223
|
-
end
|
224
|
-
|
225
202
|
def test_highlight
|
226
203
|
highlighter = dsl.highlight app.main_window, colour: NSColor.blueColor
|
227
204
|
assert_kind_of Accessibility::Highlighter, highlighter
|
228
|
-
assert_equal NSColor.blueColor, highlighter.
|
205
|
+
assert_equal NSColor.blueColor, highlighter.backgroundColor
|
229
206
|
highlighter.stop
|
230
|
-
|
207
|
+
|
208
|
+
def highlight_test
|
209
|
+
@got_called = true
|
210
|
+
end
|
211
|
+
highlighter = dsl.highlight app.main_window, color: NSColor.greenColor, timeout: 0.1
|
212
|
+
NSNotificationCenter.defaultCenter.addObserver self,
|
213
|
+
selector: 'highlight_test',
|
214
|
+
name: NSWindowWillCloseNotification,
|
215
|
+
object: highlighter
|
216
|
+
sleep 0.1
|
217
|
+
assert @got_called
|
218
|
+
end
|
219
|
+
|
220
|
+
def test_dump_works_for_nested_tab_groups
|
221
|
+
output = dsl.subtree_for app.window.tab_group
|
222
|
+
|
223
|
+
expected = [
|
224
|
+
['AX::TabGroup', 0],
|
225
|
+
['AX::RadioButton', 1], ['AX::RadioButton', 1], ['AX::TabGroup', 1],
|
226
|
+
['AX::RadioButton', 2], ['AX::RadioButton', 2], ['AX::TabGroup', 2],
|
227
|
+
['AX::RadioButton', 3], ['AX::RadioButton', 3], ['AX::TabGroup', 3],
|
228
|
+
['AX::RadioButton', 4], ['AX::RadioButton', 4],
|
229
|
+
['AX::Group', 4],
|
230
|
+
['AX::TextField', 5], ['AX::StaticText', 6],
|
231
|
+
['AX::TextField' , 5], ['AX::StaticText', 6]
|
232
|
+
]
|
233
|
+
|
234
|
+
refute_empty output
|
235
|
+
output = output.split("\n")
|
236
|
+
|
237
|
+
until output.empty?
|
238
|
+
line = output.shift
|
239
|
+
klass, indents = expected.shift
|
240
|
+
assert_equal indents, line.match(/^\t*/).to_a.first.length, line
|
241
|
+
line.strip!
|
242
|
+
assert_match /^\#<#{klass}/, line
|
243
|
+
end
|
231
244
|
end
|
232
245
|
|
233
246
|
def test_screenshot
|
@@ -331,15 +344,4 @@ class TestAccessibilityDSL < MiniTest::Unit::TestCase
|
|
331
344
|
pop_up.menu_item.perform :cancel unless pop_up.children.empty?
|
332
345
|
end
|
333
346
|
|
334
|
-
def test_contextual_menu
|
335
|
-
Mouse.move_to app.window.web_area
|
336
|
-
menu = nil
|
337
|
-
dsl.right_click do
|
338
|
-
menu = dsl.contextual_menu
|
339
|
-
end
|
340
|
-
refute_nil menu, 'did not find the contextual menu'
|
341
|
-
refute_nil menu.item(title: 'Reload')
|
342
|
-
menu.perform :cancel
|
343
|
-
end
|
344
|
-
|
345
347
|
end
|
@@ -4,7 +4,6 @@ require 'accessibility/graph'
|
|
4
4
|
class TestAccessibilityGraph < MiniTest::Unit::TestCase
|
5
5
|
|
6
6
|
def test_generate
|
7
|
-
skip 'graphs are broken right now'
|
8
7
|
p = Accessibility::Graph.new(app.main_window).generate_png!
|
9
8
|
assert File.exists? p
|
10
9
|
assert_match /^PNG image/, `file --brief #{p}`
|
@@ -72,14 +72,14 @@ class TestAccessibilityQualifier < MiniTest::Unit::TestCase
|
|
72
72
|
|
73
73
|
def test_qualifies_based_on_param_attribute_value
|
74
74
|
e = app.attribute(:main_window).attribute(:title_ui_element)
|
75
|
-
q = qualifier(:StaticText, [:string_for_range, 0
|
75
|
+
q = qualifier(:StaticText, [:string_for_range, CFRange.new(0,2)] => 'AX' )
|
76
76
|
assert q.qualifies? e
|
77
77
|
refute q.qualifies? list
|
78
78
|
end
|
79
79
|
|
80
80
|
def test_qualifies_based_on_param_attribute_regexp_match
|
81
81
|
e = app.attribute(:main_window).attribute(:title_ui_element)
|
82
|
-
q = qualifier(:StaticText, [:string_for_range, 0
|
82
|
+
q = qualifier(:StaticText, [:string_for_range, CFRange.new(0,2)] => /AX/ )
|
83
83
|
assert q.qualifies? e
|
84
84
|
refute q.qualifies? items.sample
|
85
85
|
end
|
@@ -13,13 +13,6 @@ class TestAXApplication < MiniTest::Unit::TestCase
|
|
13
13
|
assert_equal app, AX::Application.new(running_app)
|
14
14
|
end
|
15
15
|
|
16
|
-
def test_initialize_causing_app_to_launch
|
17
|
-
app = AX::Application.new('com.apple.Grab')
|
18
|
-
assert_kind_of AX::Application, app
|
19
|
-
ensure
|
20
|
-
app.terminate if app
|
21
|
-
end
|
22
|
-
|
23
16
|
def test_can_set_focus_and_blur_app # lol, blur
|
24
17
|
assert app.set :focused, false
|
25
18
|
refute app.active?
|
@@ -32,7 +25,7 @@ class TestAXApplication < MiniTest::Unit::TestCase
|
|
32
25
|
assert app.attribute :focused?
|
33
26
|
|
34
27
|
ensure
|
35
|
-
running_app.activateWithOptions
|
28
|
+
running_app.activateWithOptions NSApplicationActivateIgnoringOtherApps
|
36
29
|
end
|
37
30
|
|
38
31
|
def test_can_hide_and_unhide_app
|
@@ -49,7 +42,7 @@ class TestAXApplication < MiniTest::Unit::TestCase
|
|
49
42
|
refute app.hidden?
|
50
43
|
|
51
44
|
ensure
|
52
|
-
running_app.activateWithOptions
|
45
|
+
running_app.activateWithOptions NSApplicationActivateIgnoringOtherApps
|
53
46
|
end
|
54
47
|
|
55
48
|
def test_set_calls_super
|
@@ -10,13 +10,6 @@ class TestAXElement < MiniTest::Unit::TestCase
|
|
10
10
|
assert_equal app.window.close_button, list.first
|
11
11
|
end
|
12
12
|
|
13
|
-
def test_parameterized_attribute_normalizes_ranges
|
14
|
-
text = app.main_window.static_text
|
15
|
-
expected = text.value
|
16
|
-
actual = text.parameterized_attribute :string_for_range, 0..-1
|
17
|
-
assert_equal expected, actual
|
18
|
-
end
|
19
|
-
|
20
13
|
def test_search_singular_returns_array
|
21
14
|
result = app.search(:window)
|
22
15
|
assert_kind_of AX::Window, result
|
@@ -50,13 +43,6 @@ class TestAXElement < MiniTest::Unit::TestCase
|
|
50
43
|
box.set :value, '' if box
|
51
44
|
end
|
52
45
|
|
53
|
-
def test_parameterized_attribute_through_method_missing
|
54
|
-
field = app.window.static_text
|
55
|
-
expected = field.parameterized_attribute :string_for_range, 0..2
|
56
|
-
actual = field.string_for_range 0..2
|
57
|
-
assert_equal expected, actual
|
58
|
-
end
|
59
|
-
|
60
46
|
def test_invalid
|
61
47
|
refute app.invalid?
|
62
48
|
|
@@ -66,30 +52,4 @@ class TestAXElement < MiniTest::Unit::TestCase
|
|
66
52
|
assert bye.invalid?
|
67
53
|
end
|
68
54
|
|
69
|
-
def test_dump_works_for_nested_tab_groups
|
70
|
-
output = app.window.tab_group.inspect_subtree
|
71
|
-
|
72
|
-
expected = [
|
73
|
-
['AX::TabGroup', 0],
|
74
|
-
['AX::RadioButton', 1], ['AX::RadioButton', 1], ['AX::TabGroup', 1],
|
75
|
-
['AX::RadioButton', 2], ['AX::RadioButton', 2], ['AX::TabGroup', 2],
|
76
|
-
['AX::RadioButton', 3], ['AX::RadioButton', 3], ['AX::TabGroup', 3],
|
77
|
-
['AX::RadioButton', 4], ['AX::RadioButton', 4],
|
78
|
-
['AX::Group', 4],
|
79
|
-
['AX::TextField', 5], ['AX::StaticText', 6],
|
80
|
-
['AX::TextField' , 5], ['AX::StaticText', 6]
|
81
|
-
]
|
82
|
-
|
83
|
-
refute_empty output
|
84
|
-
output = output.split("\n")
|
85
|
-
|
86
|
-
until output.empty?
|
87
|
-
line = output.shift
|
88
|
-
klass, indents = expected.shift
|
89
|
-
assert_equal indents, line.match(/^\t*/).to_a.first.length, line
|
90
|
-
line.strip!
|
91
|
-
assert_match /^\#<#{klass}/, line
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
55
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'test/integration/helper'
|
2
|
+
require 'minitest/ax_elements'
|
3
|
+
|
4
|
+
class TestMiniTestAssertions < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
def test_assert_has_child
|
7
|
+
expected = app.window
|
8
|
+
|
9
|
+
assert_equal expected, assert_has_child(app, :window)
|
10
|
+
assert_equal expected, assert_has_child(app, :window, title: 'AXElementsTester')
|
11
|
+
|
12
|
+
assert_has_child(app, :window) { |_| @got_called = true }
|
13
|
+
assert @got_called
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_assert_has_child_raises_in_failure_cases
|
17
|
+
e = assert_raises(MiniTest::Assertion) { assert_has_child app, :button }
|
18
|
+
assert_match /to have Button as a child/, e.message
|
19
|
+
|
20
|
+
e = assert_raises(MiniTest::Assertion) { assert_has_child app, :button, title: "Press" }
|
21
|
+
assert_match %r{to have Button\(title: "Press"\) as a child}, e.message
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_assert_has_descendent
|
25
|
+
expected = app.main_window.check_box
|
26
|
+
|
27
|
+
assert_equal expected, assert_has_descendent(app,:check_box)
|
28
|
+
assert_equal expected, assert_has_descendent(app,:check_box, title: /Box/)
|
29
|
+
|
30
|
+
assert_has_descendent(app, :check_box) { |_| @got_called = true }
|
31
|
+
assert @got_called
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_assert_has_descendent_raises_in_failure_cases
|
35
|
+
e = assert_raises(MiniTest::Assertion) {
|
36
|
+
assert_has_descendent(app.main_window.slider, :window, title: /Cake/)
|
37
|
+
}
|
38
|
+
assert_match /to have Window\(title: \/Cake\/\) as a descendent/, e.message
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_assert_shortly_has
|
42
|
+
assert_equal app.window, assert_shortly_has(:window, parent: app)
|
43
|
+
assert_equal app.check_box, assert_shortly_has(:check_box, ancestor: app)
|
44
|
+
|
45
|
+
assert_shortly_has(:window, parent: app) { @got_called = true }
|
46
|
+
assert @got_called
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_assert_shortly_has_raises_in_failure_cases
|
50
|
+
e = assert_raises(MiniTest::Assertion) { assert_shortly_has(:button, parent: app, timeout: 0) }
|
51
|
+
assert_match /to have child Button before a timeout occurred/, e.message
|
52
|
+
|
53
|
+
e = assert_raises(MiniTest::Assertion) { assert_shortly_has(:table, ancestor: app.menu_bar_item, timeout: 0) }
|
54
|
+
assert_match /to have descendent Table before a timeout occurred/, e.message
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_refute_has_child
|
58
|
+
assert_nil refute_has_child(app, :button)
|
59
|
+
assert_nil refute_has_child(app, :window, title: 'Herp Derp')
|
60
|
+
|
61
|
+
result = refute_has_child(app, :window) { |x| x.title == 'Herp Derp' }
|
62
|
+
assert_nil result
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_refute_has_child_raises_in_failure_cases
|
66
|
+
e = assert_raises(MiniTest::Assertion) { refute_has_child app, :window }
|
67
|
+
assert_match /NOT to have #{Regexp.escape(app.window.inspect)} as a child/, e.message
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_refute_has_descendent
|
71
|
+
slider = app.main_window.slider
|
72
|
+
|
73
|
+
assert_nil refute_has_descendent(slider, :window)
|
74
|
+
assert_nil refute_has_descendent(slider, :element, title: 'Rhubarb')
|
75
|
+
|
76
|
+
result = refute_has_descendent slider, :element do |x|
|
77
|
+
@got_called = true
|
78
|
+
x.attributes.include?(:title) && x.title == 'Rhubarb'
|
79
|
+
end
|
80
|
+
assert_nil result
|
81
|
+
assert @got_called
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_refute_has_descendent_raises_in_failure_cases
|
85
|
+
e = assert_raises(MiniTest::Assertion) { refute_has_descendent app, :window }
|
86
|
+
assert_match /#{Regexp.escape(app.window.inspect)} as a descendent/, e.message
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'test/integration/helper'
|
3
|
+
require 'rspec/expectations/ax_elements'
|
4
|
+
|
5
|
+
class TestRSpecMatchers < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
|
8
|
+
def test_have_child_should_failure_message
|
9
|
+
e = app.main_window.slider
|
10
|
+
m = have_child(:window)
|
11
|
+
|
12
|
+
refute m.matches?(e)
|
13
|
+
assert_equal "Expected #{e.inspect} to have child Window", m.failure_message_for_should
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_have_child_should_not_failure_message
|
17
|
+
e = app.window
|
18
|
+
m = have_child(:window)
|
19
|
+
|
20
|
+
refute m.does_not_match?(app)
|
21
|
+
assert_equal "Expected #{app.inspect} to NOT have child #{e.inspect}", m.failure_message_for_should_not
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_have_child_description
|
25
|
+
m = have_child(:window) { }
|
26
|
+
assert_equal 'should have a child that matches Window[✔]', m.description
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
def test_have_descendent_should_failure_message
|
32
|
+
m = have_descendent(:button)
|
33
|
+
e = app.main_window.slider
|
34
|
+
|
35
|
+
refute m.matches?(e)
|
36
|
+
assert_equal "Expected #{e.inspect} to have descendent Button", m.failure_message_for_should
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_have_descendent_should_not_failure_message
|
40
|
+
m = have_descendant(:window)
|
41
|
+
e = app.window
|
42
|
+
|
43
|
+
refute m.does_not_match?(app)
|
44
|
+
assert_equal "Expected #{app.inspect} to NOT have descendent #{e.inspect}", m.failure_message_for_should_not
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_have_descendent_description
|
48
|
+
m = have_descendent(:button)
|
49
|
+
assert_equal 'should have a descendent matching Button', m.description
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
def test_shortly_have_child_should_failure_message
|
55
|
+
m = shortly_have_child(:button, timeout: 0) { }
|
56
|
+
e = app.main_window.slider
|
57
|
+
|
58
|
+
refute m.matches?(e)
|
59
|
+
assert_equal "Expected #{e.inspect} to have child Button[✔] before a timeout occurred",
|
60
|
+
m.failure_message_for_should
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_shortly_have_child_should_not_failure_message
|
64
|
+
m = shortly_have_child(:window)
|
65
|
+
e = app
|
66
|
+
|
67
|
+
refute m.does_not_match?(e)
|
68
|
+
assert_equal "Expected #{e.inspect} to NOT have child #{e.window.inspect} before a timeout occurred",
|
69
|
+
m.failure_message_for_should_not
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_shortly_have_child_description
|
73
|
+
m = shortly_have_child(:button)
|
74
|
+
assert_equal 'should have a child that matches Button before a timeout occurs', m.description
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
def test_shortly_have_descendent_should_failure_message
|
80
|
+
m = shortly_have_descendent(:button, timeout: 0)
|
81
|
+
e = app.main_window.slider
|
82
|
+
|
83
|
+
refute m.matches?(e)
|
84
|
+
assert_equal "Expected #{e.inspect} to have descendent Button before a timeout occurred",
|
85
|
+
m.failure_message_for_should
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_shortly_have_descendent_should_not_failure_message
|
89
|
+
m = shortly_have_descendent(:window)
|
90
|
+
e = app
|
91
|
+
|
92
|
+
refute m.does_not_match?(e)
|
93
|
+
assert_equal "Expected #{e.inspect} to NOT have descendent #{e.window.inspect} before a timeout occurred",
|
94
|
+
m.failure_message_for_should_not
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_shortly_have_descendent_description
|
98
|
+
m = shortly_have_descendent(:button)
|
99
|
+
assert_equal 'should have a descendent matching Button before a timeout occurs', m.description
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|