atspi_app_driver 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +92 -0
  4. data/Rakefile +2 -0
  5. data/gems.rb +3 -0
  6. data/lib/atspi_app_driver.rb +132 -0
  7. metadata +90 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 509b787e88981adcc2bf586c981e47c7d2739584
4
+ data.tar.gz: 392fe1910cac1d8726bd770205a3328af8a9691b
5
+ SHA512:
6
+ metadata.gz: b283db9f341667f37781ed06e5e0a85dd080fa286adc6735d05ec333e5be4d4412c63ba44aabcd5f77c2945cddc6487a10b7364900b983e8fda1f5d00c4c3f0f
7
+ data.tar.gz: c3b2d4150d7a2fede09ead523846335454415512f38ca7416d7a2d61f39a1d1d2e2c0954344040987e0a89b25a119b8a23c035b55f516b4802d402e0181ae74c
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2015 Matijs van Zuijlen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ 'Software'), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # Atspi App Driver
2
+
3
+ Test driver for the Atspi-enabled applications. Takes care of boot and
4
+ shutdown, and provides a handle on the GUI's main UI frame.
5
+
6
+ ## Usage
7
+
8
+ This driver assumes your application lives in `bin/` and uses additional ruby
9
+ code in `lib/`.
10
+
11
+ Say, your application is called `foo`. Then, in your tests, do something like this:
12
+
13
+ require 'atspi_app_driver'
14
+
15
+ describe 'The application' do
16
+ before do
17
+ @driver = AtspiAppDriver.new('foo')
18
+
19
+ # This will boot `ruby -Ilib bin/foo`, wait for its main window to appear,
20
+ # and focus it.
21
+ @driver.boot
22
+ end
23
+
24
+ it 'does stuff' do
25
+ # Fetch the main window's atspi object
26
+ frame = @driver.frame
27
+
28
+ # You can now interact with the window's objects
29
+
30
+ # Select item matching /bar/ from combo box:
31
+ box = frame.find_role :combo_box
32
+ item = box.find_role :menu_item, /bar/
33
+ box.get_action_name(0).must_equal 'press'
34
+ box.do_action 0
35
+ item.get_action_name(0).must_equal 'click'
36
+ item.do_action 0
37
+
38
+ # Fetch contents of a text box
39
+ textbox = frame.find_role :text
40
+ textbox.get_text(0, 100).must_equal 'Foo bar baz'
41
+
42
+ # Quit application
43
+ @driver.press_ctrl_q
44
+
45
+ # Check exit status
46
+ status = @driver.cleanup
47
+ status.exitstatus.must_equal 0
48
+ end
49
+
50
+ after do
51
+ # Ensure application is cleaned up
52
+ @driver.cleanup
53
+ end
54
+ end
55
+
56
+ ## Installation
57
+
58
+ gem install atspi_app_driver
59
+
60
+ ## Dependencies
61
+
62
+ Atspi App Driver needs atspi's GIR data, and needs to be able to interact with
63
+ the application via atspi and atk. The below are suggested packages to install.
64
+ Corrections are welcome, of course.
65
+
66
+ ### Debian
67
+
68
+ This should work on Debian unstable.
69
+
70
+ sudo apt-get install dbus
71
+ sudo apt-get install libgirepository1.0-dev gobject-introspection
72
+ sudo apt-get install gir1.2-atspi-2.0 libatk-adaptor
73
+
74
+ ### Ubuntu
75
+
76
+ Please try the instructions for Debian. This will probably not work on Ubuntu
77
+ 12.04. Again, corrections and additions are welcome.
78
+
79
+ ### Other OS
80
+
81
+ To be determined. Please contribute back your experience in getting Atspi App
82
+ Driver working on your favorite operation system.
83
+
84
+ ## Contributing
85
+
86
+ Contributions are welcome! Please feel free to create issues or pull requests
87
+ on GitHub.
88
+
89
+ ## License
90
+
91
+ Copyright © 2015 [Matijs van Zuijlen](http://www.matijs.net).
92
+ See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'rake/clean'
2
+ require 'bundler/gem_tasks'
data/gems.rb ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,132 @@
1
+ require 'gir_ffi'
2
+
3
+ GirFFI.setup :Atspi
4
+ Atspi.load_class :Accessible
5
+
6
+ # Utility monkey-patches for the Atspi::Accessible class
7
+ module AtspiAccessiblePatches
8
+ def each_child
9
+ child_count.times do |i|
10
+ child = get_child_at_index i
11
+ yield child if child
12
+ end
13
+ end
14
+
15
+ def find_role role, regex = //
16
+ return self if role == self.role && name =~ regex
17
+ each_child do |child|
18
+ result = child.find_role role, regex
19
+ return result if result
20
+ end
21
+ nil
22
+ end
23
+
24
+ def inspect_recursive level = 0, maxlevel = 4
25
+ each_child do |child|
26
+ puts "#{' ' * level} > name: #{child.name}; role: #{child.role}"
27
+ child.inspect_recursive(level + 1) unless level >= maxlevel
28
+ end
29
+ end
30
+ end
31
+
32
+ Atspi::Accessible.include AtspiAccessiblePatches
33
+
34
+ # Test driver for the Atspi-enabled applications. Takes care of boot and
35
+ # shutdown, and provides a handle on the GUI's main UI frame.
36
+ class AtspiAppDriver
37
+ def initialize app_name, verbose: false
38
+ @app_file = "bin/#{app_name}"
39
+ @lib_dir = 'lib'
40
+ @app_name = app_name
41
+ @pid = nil
42
+ @verbose = verbose
43
+ @frame = nil
44
+ end
45
+
46
+ attr_reader :frame
47
+
48
+ def boot test_timeout: 30, exit_timeout: 10, arguments: []
49
+ raise 'Already booted' if @pid
50
+
51
+ spawn_process(arguments)
52
+
53
+ @cleanup = false
54
+
55
+ @frame = find_and_focus_frame
56
+
57
+ @thread = Thread.new do
58
+ wait_for('test to be done', test_timeout) { @cleanup }
59
+ wait_for('pid to go away', exit_timeout) { !@pid }
60
+ kill_process if @pid
61
+ end
62
+ end
63
+
64
+ def spawn_process arguments
65
+ command = "ruby -I#{@lib_dir} #{@app_file} #{arguments.join(' ')}"
66
+ log "About to spawn: `#{command}`"
67
+ @pid = Process.spawn command
68
+ end
69
+
70
+ def press_ctrl_q
71
+ Atspi.generate_keyboard_event(37, nil, :press)
72
+ Atspi.generate_keyboard_event(24, nil, :pressrelease)
73
+ Atspi.generate_keyboard_event(37, nil, :release)
74
+ end
75
+
76
+ def cleanup
77
+ status = exit_status
78
+ @pid = nil
79
+ @thread.join if @thread
80
+ status
81
+ end
82
+
83
+ private
84
+
85
+ def find_and_focus_frame
86
+ acc = wait_for('app to appear', 10) { find_app }
87
+ raise 'App not found' unless acc
88
+
89
+ frame = acc.get_child_at_index 0
90
+ frame.role.must_equal :frame
91
+ frame.grab_focus
92
+
93
+ frame
94
+ end
95
+
96
+ def kill_process
97
+ log "About to kill child process #{@pid}"
98
+ Process.kill 'KILL', @pid
99
+ end
100
+
101
+ def log message
102
+ warn message if @verbose
103
+ end
104
+
105
+ def find_app
106
+ desktop = Atspi.get_desktop(0)
107
+ desktop.each_child do |child|
108
+ return child if child.name == @app_name
109
+ end
110
+ nil
111
+ end
112
+
113
+ # TODO: User timeout
114
+ def wait_for description, _timeout
115
+ start = Time.now
116
+ # Try for 0.01 * 50 * (50 + 1) / 2 = 12.75 seconds
117
+ value = 50.times.each do |num|
118
+ result = yield
119
+ break result if result
120
+ sleep 0.01 * (num + 1)
121
+ end
122
+ log "Waited #{Time.now - start} seconds for #{description}"
123
+ value
124
+ end
125
+
126
+ def exit_status
127
+ return unless @pid
128
+ @cleanup = true
129
+ _, status = Process.wait2 @pid
130
+ status
131
+ end
132
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: atspi_app_driver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Matijs van Zuijlen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gir_ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.7.9
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.7.9
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.1'
55
+ description:
56
+ email:
57
+ - matijs@matijs.net
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - LICENSE
63
+ - README.md
64
+ - Rakefile
65
+ - gems.rb
66
+ - lib/atspi_app_driver.rb
67
+ homepage: http://www.github.com/mvz/atspi_app_driver
68
+ licenses: []
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.4.5
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Test GNOME applications using Atspi
90
+ test_files: []