AXElements 0.9.0 → 1.0.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- 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
|