te3270-jruby 0.1-universal-java-1.7

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 93a3523e4b9494eadcae9e2b7e6fc3a5c8686e7f
4
+ data.tar.gz: 02e4fb70ce6f56ff1cb742e472b423ccfa5b05c0
5
+ SHA512:
6
+ metadata.gz: d308752e3cefcbe827196919431f6fd30e1eac05df1eb475653fb905f3b23fe6cbf779622a50f329bb2874142956de57f4a9e1fca2a197933cbb3178d23565fc
7
+ data.tar.gz: d056aa52e60c13e124ef8af348beae68c92dc94f6c885625a8b9ad5ba5965db39298f333ecd374757bdcd7c860235e873d8548085deb024b13b8f709d4232759
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: jruby
2
+ rvm:
3
+ - 1.7.10
data/ChangeLog ADDED
@@ -0,0 +1,2 @@
1
+ === Version 0.1 / 2014-2-9
2
+ * Initial release with basic functionality for EXTRA X-treme! and Quick3270
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ require 'rbconfig'
4
+
5
+ gem 'rake'
6
+ gem 'fuubar'
7
+ gem 'guard-rspec'
8
+ gem 'wdm', '>= 0.1.0'
9
+ gem 'rb-inotify'
10
+
11
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,7 @@
1
+
2
+ guard :rspec, :all_on_start => true, :cmd => 'rspec --color --format Fuubar' do
3
+ watch(%r{^spec/*/.+_spec\.rb$})
4
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ end
7
+
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Pradeep K. Macharla
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # TE3270 for jruby
2
+
3
+ This gem can be used to drive a 3270 terminal emulator in a jruby environment. The code has been tested on jruby 1.7.10
4
+ You have to have a supported emulator installed on the
5
+ machines on which you use the gem. Currently the only supported emulators are
6
+ [EXTRA! X-treme](http://www.attachmate.com/Products/Terminal+Emulation/Extra/xtreme/extra-x-treme.htm) by
7
+ Attachmate and [Quick3270](http://www.dn-computing.com/Quick3270.htm) by DN-Computing. These are commercial
8
+ products and you will need to purchase one of them in order to use this gem. We do plan to support other
9
+ emulators as time permits.
10
+
11
+ ## Documentation
12
+
13
+ You can view the RDocs for this project [here](http://rdoc.info/github/machzqcq/te3270/master/frames).
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ gem 'te3270-jruby'
20
+
21
+ And then execute:
22
+
23
+ $ bundle
24
+
25
+ Or install it yourself as:
26
+
27
+ $ gem install te3270-jruby
28
+
29
+ ## Usage
30
+
31
+ You can create classes that are similar to page-object classes. In these classes you can define
32
+ the various fields that you wish to interact with on the screen.
33
+
34
+ class MainframeScreen
35
+ include TE3270
36
+
37
+ text_field(:userid, 10, 30, 20)
38
+ text_field(:password, 12, 30, 20)
39
+
40
+ def login(username, password)
41
+ self.userid = username
42
+ self.password = password
43
+ end
44
+ end
45
+
46
+ emulator = TE3270.emulator_for :extra do |platform|
47
+ platform.session_file = 'sessionfile.edp'
48
+ end
49
+ my_screen = MainframeScreen.new(emulator)
50
+ my_screen.userid = 'the_id'
51
+ my_screen.password = 'the_password'
52
+
53
+ If you are using this gem with cucumber then you can register the ScreenFactory module with the
54
+ cucumber World like this:
55
+
56
+ World(TE3270::ScreenFactory)
57
+
58
+ You also need to setup some hooks to start and stop the emulator:
59
+
60
+ Begin do
61
+ @emulator = TE3270.emulator_for :extra do |platform|
62
+ platform.session_file = 'sessionfile.edp'
63
+ end
64
+ end
65
+
66
+ After do
67
+ TE3270.disconnect(@emulator)
68
+ end
69
+
70
+ This allows you to use the `on` method in your step definitions like this:
71
+
72
+ on(MainframeScreen).login('the_user', 'the_password')
73
+
74
+ or you can use the version of `on` that takes a block like this:
75
+
76
+ on(MainframeScreen) do |screen|
77
+ screen.userid = 'the_id'
78
+ screen.password = 'the_password'
79
+ end
80
+
81
+ ## Contributing
82
+
83
+ 1. Fork it
84
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
85
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
86
+ 4. Push to the branch (`git push origin my-new-feature`)
87
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,30 @@
1
+
2
+ module TE3270
3
+ module Accessors
4
+
5
+ #
6
+ # adds two methods to the screen object - one to set text in a text field,
7
+ # another to retrieve text from a text field.
8
+ #
9
+ # @example
10
+ # text_field(:first_name, 23,45,20)
11
+ # # will generate 'first_name', 'first_name=' method
12
+ #
13
+ # @param [String] the name used for the generated methods
14
+ # @param [FixedNum] row number of the location
15
+ # @param [FixedNum] column number of the location
16
+ # @param [FixedNum] length of the text field
17
+ # @param [true|false] editable is by default true
18
+ #
19
+ def text_field(name, row, column, length, editable=true)
20
+ define_method(name) do
21
+ platform.get_string(row, column, length)
22
+ end
23
+
24
+ define_method("#{name}=") do |value|
25
+ platform.put_string(value, row, column)
26
+ end if editable
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,21 @@
1
+ require 'te3270/emulators/extra'
2
+ require 'te3270/emulators/quick3270'
3
+
4
+ module TE3270
5
+ #
6
+ # Provides a mapping between a key used in the +emulator_for+ method
7
+ # and the class that implements the access to the emulator.
8
+ #
9
+ module EmulatorFactory
10
+
11
+ EMULATORS = {
12
+ extra: TE3270::Emulators::Extra,
13
+ quick3270: TE3270::Emulators::Quick3270
14
+ }
15
+
16
+ def self.emulator_for(platform)
17
+ EMULATORS[platform]
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,212 @@
1
+ require 'jruby-win32ole'
2
+
3
+ require 'java'
4
+ include_class 'java.awt.Dimension'
5
+ include_class 'java.awt.Rectangle'
6
+ include_class 'java.awt.Robot'
7
+ include_class 'java.awt.Toolkit'
8
+ include_class 'java.awt.event.InputEvent'
9
+ include_class 'java.awt.image.BufferedImage'
10
+ include_class 'javax.imageio.ImageIO'
11
+
12
+ module TE3270
13
+ module Emulators
14
+ #
15
+ # This class has the code necessary to communicate with the terminal emulator called EXTRA! X-treme.
16
+ # You can use this emulator by providing the +:extra+ parameter to the constructor of your screen
17
+ # object or by passing the same value to the +emulator_for+ method on the +TE3270+ module.
18
+ #
19
+ class Extra
20
+
21
+ attr_writer :session_file, :visible, :window_state, :max_wait_time
22
+
23
+
24
+ #
25
+ # Creates a method to connect to Extra System. This method expects a block in which certain
26
+ # platform specific values can be set. Extra can take the following parameters.
27
+ #
28
+ # * session_file - this value is required and should be the filename of the session.
29
+ # * visible - determines if the emulator is visible or not. If not set it will default to +true+.
30
+ # * window_state - determines the state of the session window. Valid values are +:minimized+,
31
+ # +:normal+, and +:maximized+. If not set it will default to +:normal+.
32
+ #
33
+ # @example Example calling screen object constructor with a block
34
+ # screen_object = MyScreenObject.new(:extra)
35
+ # screen_object.connect do |emulator|
36
+ # emulator.session_file = 'path_to_session_file'
37
+ # emulator.visible = true
38
+ # emulator.window_state = :maximized
39
+ # end
40
+ #
41
+ def connect
42
+ start_extra_system
43
+
44
+ yield self if block_given?
45
+ raise 'The session file must be set in a block when calling connect with the Extra emulator.' if @session_file.nil?
46
+ open_session
47
+ @screen = session.Screen
48
+ @area = screen.SelectAll
49
+ end
50
+
51
+ #
52
+ # Disconnects the Extra System connection
53
+ #
54
+ def disconnect
55
+ system.Quit
56
+ end
57
+
58
+ #
59
+ # Extracts text of specified length from a start point.
60
+ #
61
+ # @param [Fixnum] row the x coordinate of location on the screen.
62
+ # @param [Fixnum] column the y coordinate of location on the screen.
63
+ # @param [Fixnum] length the length of string to extract
64
+ # @return [String]
65
+ #
66
+ def get_string(row, column, length)
67
+ screen.GetString(row, column, length)
68
+ end
69
+
70
+ #
71
+ # Puts string at the coordinates specified.
72
+ #
73
+ # @param [String] str the string to set
74
+ # @param [Fixnum] row the x coordinate of the location on the screen.
75
+ # @param [Fixnum] column the y coordinate of the location on the screen.
76
+ #
77
+ def put_string(str, row, column)
78
+ screen.PutString(str, row, column)
79
+ quiet_period
80
+ end
81
+
82
+ #
83
+ # Sends keystrokes to the host, including function keys.
84
+ #
85
+ # @param [String] keys keystokes up to 255 in length
86
+ #
87
+ def send_keys(keys)
88
+ screen.SendKeys(keys)
89
+ quiet_period
90
+ end
91
+
92
+ #
93
+ # Wait for the string to appear at the specified location
94
+ #
95
+ # @param [String] str the string to wait for
96
+ # @param [Fixnum] row the x coordinate of location
97
+ # @param [Fixnum] column the y coordinate of location
98
+ #
99
+ def wait_for_string(str, row, column)
100
+ wait_for do
101
+ screen.WaitForString(str, row, column)
102
+ end
103
+ end
104
+
105
+ #
106
+ # Waits for the host to not send data for a specified number of seconds
107
+ #
108
+ # @param [Fixnum] seconds the maximum number of seconds to wait
109
+ #
110
+ def wait_for_host(seconds)
111
+ wait_for(seconds) do
112
+ screen.WaitHostQuiet
113
+ end
114
+ end
115
+
116
+ #
117
+ # Waits until the cursor is at the specified location.
118
+ #
119
+ # @param [Fixnum] row the x coordinate of the location
120
+ # @param [Fixnum] column the y coordinate of the location
121
+ #
122
+ def wait_until_cursor_at(row, column)
123
+ wait_for do
124
+ screen.WaitForCursor(row, column)
125
+ end
126
+ end
127
+
128
+ #
129
+ # Creates a method to take screenshot of the active screen. If you have set the +:visible+
130
+ # property to false it will be made visible prior to taking the screenshot and then changed
131
+ # to invisible after.
132
+ #
133
+ # @param [String] filename the path and name of the screenshot file to be saved
134
+ #
135
+ def screenshot(filename)
136
+ File.delete(filename) if File.exists?(filename)
137
+ session.Visible = true unless visible
138
+
139
+ toolkit = Toolkit::getDefaultToolkit()
140
+ screen_size = toolkit.getScreenSize()
141
+ rect = Rectangle.new(screen_size)
142
+ robot = Robot.new
143
+ image = robot.createScreenCapture(rect)
144
+ f = java::io::File.new(filename)
145
+ ImageIO::write(image, "png", f)
146
+
147
+ session.Visible = false unless visible
148
+ end
149
+
150
+ #
151
+ # Returns the text of the active screen
152
+ #
153
+ # @return [String]
154
+ #
155
+ def text
156
+ area.Value
157
+ end
158
+
159
+ private
160
+
161
+ attr_reader :system, :sessions, :session, :screen, :area
162
+
163
+ WINDOW_STATES = {
164
+ minimized: 0,
165
+ normal: 1,
166
+ maximized: 2
167
+ }
168
+
169
+ def wait_for(seconds = system.TimeoutValue / 1000)
170
+ wait_collection = yield
171
+ wait_collection.Wait(seconds * 1000)
172
+ end
173
+
174
+ def quiet_period
175
+ wait_for_host(max_wait_time)
176
+ end
177
+
178
+ def max_wait_time
179
+ @max_wait_time ||= 1
180
+ end
181
+
182
+ def window_state
183
+ @window_state.nil? ? 1 : WINDOW_STATES[@window_state]
184
+ end
185
+
186
+ def visible
187
+ @visible.nil? ? true : @visible
188
+ end
189
+
190
+ def hide_splash_screen
191
+ version = system.Version
192
+ sessions.VisibleOnStartup = true if version.to_i >= 9
193
+ end
194
+
195
+ def open_session
196
+ @sessions = system.Sessions
197
+ hide_splash_screen
198
+ @session = sessions.Open @session_file
199
+ @session.WindowState = window_state
200
+ @session.Visible = visible
201
+ end
202
+
203
+ def start_extra_system
204
+ begin
205
+ @system = WIN32OLE.new('EXTRA.System')
206
+ rescue Exception => e
207
+ $stderr.puts e
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
@@ -0,0 +1,191 @@
1
+ require 'jruby-win32ole'
2
+ require 'java'
3
+
4
+ include_class 'java.awt.Dimension'
5
+ include_class 'java.awt.Rectangle'
6
+ include_class 'java.awt.Robot'
7
+ include_class 'java.awt.Toolkit'
8
+ include_class 'java.awt.event.InputEvent'
9
+ include_class 'java.awt.image.BufferedImage'
10
+ include_class 'javax.imageio.ImageIO'
11
+
12
+ module TE3270
13
+ module Emulators
14
+
15
+ #
16
+ # This class has the code necessary to communicate with the terminal emulator called Quick3270.
17
+ # You can use this emulator by providing the +:quick+ parameter to the constructor of your screen
18
+ # object or by passing the same value to the +emulator_for+ method on the +TE3270+ module.
19
+ #
20
+
21
+ class Quick3270
22
+
23
+ attr_writer :session_file, :visible, :max_wait_time
24
+
25
+ #
26
+ # Creates a method to connect to Quick System. This method expects a block in which certain
27
+ # platform specific values can be set. Quick can take the following parameters.
28
+ #
29
+ # * session_file - this value is required and should be the filename of the session.
30
+ # * visible - determines if the emulator is visible or not. If not set it will default to +true+.
31
+ #
32
+ # @example Example calling screen object constructor with a block
33
+ # screen_object = MyScreenObject.new(:quick3270)
34
+ # screen_object.connect do |emulator|
35
+ # emulator.session_file = 'path_to_session_file'
36
+ # emulator.visible = true
37
+ # end
38
+ #
39
+ def connect
40
+ start_quick_system
41
+ yield self if block_given?
42
+ raise "The session file must be set in a block when calling connect with the Quick3270 emulator." if @session_file.nil?
43
+ establish_session
44
+ end
45
+
46
+ #
47
+ # Disconnects the Quick System connection
48
+ #
49
+ def disconnect
50
+ session.Disconnect
51
+ system.Application.Quit
52
+ end
53
+
54
+ #
55
+ # Extracts text of specified length from a start point.
56
+ #
57
+ # @param [Fixnum] row the x coordinate of location on the screen.
58
+ # @param [Fixnum] column the y coordinate of location on the screen.
59
+ # @param [Fixnum] length the length of string to extract
60
+ # @return [String]
61
+ #
62
+ def get_string(row, column, length)
63
+ screen.GetString(row, column, length)
64
+ end
65
+
66
+ #
67
+ # Puts string at the coordinates specified.
68
+ #
69
+ # @param [String] str the string to set
70
+ # @param [Fixnum] row the x coordinate of the location on the screen.
71
+ # @param [Fixnum] column the y coordinate of the location on the screen.
72
+ #
73
+ def put_string(str, row, column)
74
+ screen.MoveTo(row, column)
75
+ screen.PutString(str)
76
+ quiet_period
77
+ end
78
+
79
+ #
80
+ # Sends keystrokes to the host, including function keys.
81
+ #
82
+ # @param [String] keys keystokes up to 255 in length
83
+ #
84
+ def send_keys(keys)
85
+ screen.SendKeys(keys)
86
+ quiet_period
87
+ end
88
+
89
+ #
90
+ # Wait for the string to appear at the specified location
91
+ #
92
+ # @param [String] str the string to wait for
93
+ # @param [Fixnum] row the x coordinate of location
94
+ # @param [Fixnum] column the y coordinate of location
95
+ #
96
+ def wait_for_string(str, row, column)
97
+ screen.WaitForString(str, row, column)
98
+ end
99
+
100
+ #
101
+ # Waits for the host to not send data for a specified number of seconds
102
+ #
103
+ # @param [Fixnum] seconds the maximum number of seconds to wait
104
+ #
105
+ def wait_for_host(seconds)
106
+ screen.WaitHostQuiet(seconds * 1000)
107
+ end
108
+
109
+ #
110
+ # Waits until the cursor is at the specified location.
111
+ #
112
+ # @param [Fixnum] row the x coordinate of the location
113
+ # @param [Fixnum] column the y coordinate of the location
114
+ #
115
+ def wait_until_cursor_at(row, column)
116
+ screen.WaitForCursor(row, column)
117
+ end
118
+
119
+ #
120
+ # Creates a method to take screenshot of the active screen. If you have set the +:visible+
121
+ # property to false it will be made visible prior to taking the screenshot and then changed
122
+ # to invisible after.
123
+ #
124
+ # @param [String] filename the path and name of the screenshot file to be saved
125
+ #
126
+ def screenshot(filename)
127
+ File.delete(filename) if File.exists?(filename)
128
+ system.Visible = true unless visible
129
+ toolkit = Toolkit::getDefaultToolkit()
130
+ screen_size = toolkit.getScreenSize()
131
+ rect = Rectangle.new(screen_size)
132
+ robot = Robot.new
133
+ image = robot.createScreenCapture(rect)
134
+ f = java::io::File.new(filename)
135
+ ImageIO::write(image, "png", f)
136
+ system.Visible = false unless visible
137
+ end
138
+
139
+ #
140
+ # Returns the text of the active screen
141
+ #
142
+ # @return [String]
143
+ #
144
+ def text
145
+ rows = screen.Rows
146
+ columns = screen.Cols
147
+ result = ''
148
+ rows.times { |row| result += "#{screen.GetString(row+1, 1, columns)}\\n" }
149
+ result
150
+ end
151
+
152
+ private
153
+
154
+ attr_reader :system, :session, :screen
155
+
156
+ def quiet_period
157
+ screen.WaitHostQuiet(max_wait_time)
158
+ end
159
+
160
+ def max_wait_time
161
+ @max_wait_time ||= 3000
162
+ end
163
+
164
+ def visible
165
+ @visible.nil? ? true : @visible
166
+ end
167
+
168
+ def start_quick_system
169
+ begin
170
+ @system = WIN32OLE.new('Quick3270.Application')
171
+ rescue Exception => e
172
+ $stderr.puts e
173
+ end
174
+ end
175
+
176
+ def establish_session
177
+ system.Visible = visible
178
+ @session = system.ActiveSession
179
+ session.Open @session_file
180
+ @screen = session.Screen
181
+ session.Connect
182
+ connected = session.Connected
183
+ while not connected
184
+ screen.WaitHostQuiet(1000)
185
+ connected = session.Connected
186
+ end
187
+ end
188
+
189
+ end
190
+ end
191
+ end