te3270-jruby 0.1-x86-mingw32

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.
@@ -0,0 +1,78 @@
1
+
2
+ module TE3270
3
+ #
4
+ # Creates methods that are mixed in with the +TE3270+ module that represent all of the
5
+ # function keys that can be send to the system. These keys would typically be sent to
6
+ # the +send_keys_ method.
7
+ #
8
+ # @example Using a function key
9
+ # on(MyScreen).send_keys TE3270.Enter
10
+ #
11
+ module FunctionKeys
12
+
13
+ KEYS = [
14
+ 'Attn',
15
+ 'BackSpace',
16
+ 'BackTab',
17
+ 'CapsLock',
18
+ 'Clear',
19
+ 'Down',
20
+ 'Left',
21
+ 'Left2',
22
+ 'Right',
23
+ 'Right2',
24
+ 'CursorSelect',
25
+ 'Up',
26
+ 'Delete',
27
+ 'Dup',
28
+ 'Enter',
29
+ 'EraseEOF',
30
+ 'EraseInput',
31
+ 'FieldMark',
32
+ 'Home',
33
+ 'Insert',
34
+ 'BackTab',
35
+ 'NewLIne',
36
+ 'PenSel',
37
+ 'Print',
38
+ 'Reset',
39
+ 'ShiftOn',
40
+ 'SysReq',
41
+ 'Tab',
42
+ 'Pa1',
43
+ 'Pa2',
44
+ 'Pa3',
45
+ 'Pf1',
46
+ 'Pf2',
47
+ 'Pf3',
48
+ 'Pf4',
49
+ 'Pf5',
50
+ 'Pf6',
51
+ 'Pf7',
52
+ 'Pf8',
53
+ 'Pf9',
54
+ 'Pf10',
55
+ 'Pf11',
56
+ 'Pf12',
57
+ 'Pf13',
58
+ 'Pf14',
59
+ 'Pf15',
60
+ 'Pf16',
61
+ 'Pf17',
62
+ 'Pf18',
63
+ 'Pf19',
64
+ 'Pf20',
65
+ 'Pf21',
66
+ 'Pf22',
67
+ 'Pf23',
68
+ 'Pf24',
69
+ ]
70
+
71
+ KEYS.each do |key|
72
+ define_method(key) do
73
+ "<#{key}>"
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,51 @@
1
+ require 'page_navigation'
2
+
3
+ module TE3270
4
+ #
5
+ # Module to facilitate to creating of screen objects in step definitions. You
6
+ # can make the methods below available to all of your step definitions by adding
7
+ # this module to World.
8
+ #
9
+ # @example Making the ScreenFactory available to your step definitions
10
+ # World TE3270::ScreenFactory
11
+ #
12
+ # @example using a screen in a Scenario
13
+ # on MyScreen do |screen|
14
+ # screen.name = 'loginScreen'
15
+ # end
16
+ #
17
+ # If you plan to use the +navigate_to+ method you will need to ensure
18
+ # you setup the possible routes ahead of time. You must always have
19
+ # a default route in order for this to work. Here is an example of
20
+ # how you define routes:
21
+ #
22
+ # @example Example routes defined in env.rb
23
+ # TE3270::ScreenFactory.routes = {
24
+ # :default => [[ScreenOne,:method1], [ScreenTwo,:method2], [ScreenThree,:method3]],
25
+ # :another_route => [[ScreenOne,:method1, "arg1"], [ScreenTwo,:method2b], [ScreenThree,:method3]]
26
+ # }
27
+ #
28
+ # Notice the first entry of :another_route is passing an argument
29
+ # to the method.
30
+ #
31
+ module ScreenFactory
32
+ include PageNavigation
33
+
34
+ #
35
+ # Create a screen object. Also sets an instance variable +@current_screen
36
+ #
37
+ # @param [Class] screen_class a class that has included the TE3270 module
38
+ # @param [block] an optional block to be called
39
+ # @return [ScreenObject] the newly created screen object
40
+ #
41
+ # calling super when factory method called with class that is not from TE3270
42
+ def on(screen_class, &block)
43
+ return super(screen_class, &block) unless screen_class.ancestors.include? TE3270
44
+ raise '@emulator instance variable must be available to use the ScreenFactory methods' unless @emulator
45
+ @current_screen = screen_class.new @emulator
46
+ block.call @current_screen if block
47
+ @current_screen
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,4 @@
1
+ module TE3270
2
+ VERSION = "0.1"
3
+ end
4
+
data/lib/te3270.rb ADDED
@@ -0,0 +1,166 @@
1
+ require 'te3270/version'
2
+ require 'te3270/accessors'
3
+ require 'te3270/screen_factory'
4
+ require 'te3270/function_keys'
5
+ require 'te3270/emulator_factory'
6
+ require 'te3270/emulators/extra'
7
+ require 'te3270/emulators/quick3270'
8
+
9
+ #
10
+ # This gem can be used to drive a 3270 terminal emulator. You have to have a supported emulator installed on the
11
+ # machines on which you use the gem. Currently the only supported emulators are EXTRA! X-treme by Attachmate and
12
+ # Quick3270 by DN-Computing. These are commercial products and you will need to purchase one of them in order to
13
+ # use this gem. We do plan to support other emulators as time permits.
14
+ #
15
+ # This gem has been designed to work very similar to the page-object gem. You will use it to create screen objects
16
+ # for each screen in your application. Here is an example of one and how it can be used:
17
+ #
18
+ # @example Example mainframe page
19
+ # class MainframeScreen
20
+ # include TE3270
21
+ #
22
+ # text_field(:userid, 10, 30, 20, true)
23
+ # text_field(:password, 12, 30, 20, true)
24
+ # end
25
+ #
26
+ # ...
27
+ #
28
+ # emulator = TN3270.emulator_for :extra do |emulator|
29
+ # emulator.session_file = 'path_to_session_file'
30
+ # end
31
+ # my_screen = MainframeScreen.new(emulator)
32
+ # my_screen.userid = 'the_id'
33
+ # my_screen.password = 'the_password'
34
+ #
35
+ # Another option is to mixin the +TE3270::ScreenFactory+ module on use the factory methods to create the screen
36
+ # objects. If you are using Cucumber you can do this by calling the +World+ method in your env.rb file. Then
37
+ # you can use the factory and navigation methods in your step definitions.
38
+ #
39
+ # @example Registering the ScreenFactory with Cucumber World
40
+ # World(TE3270::ScreenFactory)
41
+ #
42
+ # Before do
43
+ # @emulator = TE3270.emulator_for :quick3270 do |emulator|
44
+ # emulator.session_file = 'path_to_session_file'
45
+ # end
46
+ # end
47
+ #
48
+ #
49
+ # @example Using the factory method in a step definition
50
+ # on(MainframeScreen).do_something
51
+ #
52
+ #
53
+ # @see #TE3270::ScreenFactory for more details on using the factory and navigation methods
54
+ #
55
+ module TE3270
56
+ extend FunctionKeys
57
+
58
+ def self.included(cls)
59
+ cls.extend TE3270::Accessors
60
+ end
61
+
62
+ #
63
+ # Starts the terminal emulator and makes the connection. This method requires a block
64
+ # that has emulator specific information that is necessary to complete the connection.
65
+ # To know what information you should provide in the block please see the classes in
66
+ # the TE3270::Emulators package.
67
+ #
68
+ #@param platform =[:extra,:quick3270] use :extra for Extra emulator and :quick3270 for quick emulator
69
+ #
70
+ def self.emulator_for(platform, &block)
71
+ platform_class = TE3270::EmulatorFactory.emulator_for(platform)
72
+ @platform = platform_class.new
73
+ @platform.connect &block
74
+ @platform
75
+ end
76
+
77
+ #
78
+ # Disconnects and closes the emulator
79
+ #
80
+ def self.disconnect(emulator)
81
+ emulator.disconnect
82
+ end
83
+
84
+ def initialize(platform)
85
+ @platform = platform
86
+ initialize_screen if respond_to? :initialize_screen
87
+ end
88
+
89
+ #
90
+ # Open a new screen and connect to the host. Platform specific values are set by
91
+ # passing a block to this method. To see the valid platform specific values please
92
+ # read the documentation for your emulator class in the TE3270::Emulators module.
93
+ #
94
+ def connect
95
+ platform.connect
96
+ end
97
+
98
+ #
99
+ # Disconnect from platform (extra or quick)
100
+ #
101
+ def disconnect
102
+ platform.disconnect
103
+ end
104
+
105
+ #
106
+ # Send keys on the emulator
107
+ #
108
+ def send_keys(keys)
109
+ platform.send_keys(keys)
110
+ end
111
+
112
+ #
113
+ # Retrieves the text from the current screen
114
+ #
115
+ def text
116
+ platform.text
117
+ end
118
+
119
+ #
120
+ # Takes screenshot and saves to the filename specified. If you have visibility set to false
121
+ # then this method will first of all make the screen visible, take the screenshot, and then
122
+ # make set visibility to false again.
123
+ #
124
+ # @param [String] filename of the file to be saved.
125
+ #
126
+ def screenshot(filename)
127
+ platform.screenshot(filename)
128
+ end
129
+
130
+ #
131
+ # Waits for the string to appear at the specified location
132
+ #
133
+ # @param [String] String to wait for
134
+ # @param [FixedNum] row number
135
+ # @param [FixedNum] column number
136
+ #
137
+ def wait_for_string(str, row, column)
138
+ platform.wait_for_string(str, row, column)
139
+ end
140
+
141
+ #
142
+ # Waits for the host for specified # of seconds. Default is 5 seconds
143
+ #
144
+ # @param [FixedNum] seconds to wait for
145
+ #
146
+ def wait_for_host(seconds=5)
147
+ platform.wait_for_host(seconds)
148
+ end
149
+
150
+ #
151
+ # Waits for the cursor to appear at the specified location
152
+ #
153
+ # @param [FixedNum] row number
154
+ # @param [FixedNum] column number
155
+ #
156
+ def wait_until_cursor_at(row, column)
157
+ platform.wait_until_cursor_at(row, column)
158
+ end
159
+
160
+ private
161
+
162
+ def platform
163
+ @platform ||= Extra.new
164
+ end
165
+
166
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ class AccessorsTestScreen
4
+ include TE3270
5
+
6
+ text_field(:method_name, 1, 2, 10, true)
7
+ text_field(:read_only, 2, 3, 12, false)
8
+ text_field(:default_editable, 3, 4, 14)
9
+ end
10
+
11
+ describe TE3270::Accessors do
12
+
13
+ let(:platform) { double('platform') }
14
+ let(:screen_object) { AccessorsTestScreen.new platform }
15
+
16
+ before(:each) do
17
+ screen_object.stub(:platform).and_return platform
18
+ end
19
+
20
+ describe "text_field accessors" do
21
+
22
+ it 'should generate a method to retrieve the value' do
23
+ expect(screen_object).to respond_to :method_name
24
+ end
25
+
26
+ it 'should generate a method to set the value' do
27
+ expect(screen_object).to respond_to :method_name=
28
+ end
29
+
30
+ it 'should not generate a method to set the value if it is not editable' do
31
+ expect(screen_object).not_to respond_to :read_only=
32
+ end
33
+
34
+ it 'should default to being editable when it is not specified' do
35
+ expect(screen_object).to respond_to :default_editable=
36
+ end
37
+
38
+ it 'should use the platform to get the text value' do
39
+ platform.should_receive(:get_string).with(1, 2, 10).and_return('abc')
40
+ expect(screen_object.method_name).to eql('abc')
41
+ end
42
+
43
+ it 'should use the platform to set the text value' do
44
+ platform.should_receive(:put_string).with('abc', 1, 2)
45
+ screen_object.method_name = 'abc'
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,182 @@
1
+ require 'spec_helper'
2
+
3
+ describe TE3270::Emulators::Extra do
4
+
5
+ let(:extra) { TE3270::Emulators::Extra.new }
6
+
7
+ before(:each) do
8
+ WIN32OLE.stub(:new).and_return extra_system
9
+ extra.instance_variable_set(:@session_file, 'the_file')
10
+ File.stub(:exists).and_return false
11
+ end
12
+
13
+
14
+ describe "global behaviors" do
15
+ it 'should start a new terminal' do
16
+ WIN32OLE.should_receive(:new).and_return(extra_system)
17
+ extra.connect
18
+ end
19
+
20
+ it 'should open a session' do
21
+ extra_sessions.should_receive(:Open).and_return(extra_session)
22
+ extra.connect
23
+ end
24
+
25
+ it 'should not display the splash screen if version is higher than 9' do
26
+ extra_system.should_receive(:Version).and_return("9.2")
27
+ extra_sessions.should_receive(:VisibleOnStartup=).with(true)
28
+ extra.connect
29
+ end
30
+
31
+ it 'should call a block allowing the session file to be set' do
32
+ extra_sessions.should_receive(:Open).with('blah.edp').and_return(extra_session)
33
+ extra.connect do |platform|
34
+ platform.session_file = 'blah.edp'
35
+ end
36
+ end
37
+
38
+ it 'should raise an error when the session file is not set' do
39
+ extra.instance_variable_set(:@session_file, nil)
40
+ expect { extra.connect }.to raise_error('The session file must be set in a block when calling connect with the Extra emulator.')
41
+ end
42
+
43
+ it 'should take the visible value from a block' do
44
+ extra_session.should_receive(:Visible=).with(false)
45
+ extra.connect do |platform|
46
+ platform.visible = false
47
+ end
48
+ end
49
+
50
+ it 'should default to visible when not specified' do
51
+ extra_session.should_receive(:Visible=).with(true)
52
+ extra.connect
53
+ end
54
+
55
+ it 'should take the window state value from the block' do
56
+ extra_session.should_receive(:WindowState=).with(2)
57
+ extra.connect do |platform|
58
+ platform.window_state = :maximized
59
+ end
60
+ end
61
+
62
+ it 'should default to window state normal when not specified' do
63
+ extra_session.should_receive(:WindowState=).with(1)
64
+ extra.connect
65
+ end
66
+
67
+ it 'should default to being visible' do
68
+ extra_session.should_receive(:Visible=).with(true)
69
+ extra.connect
70
+ end
71
+
72
+ it 'should get the screen for the active session' do
73
+ extra_session.should_receive(:Screen).and_return(extra_screen)
74
+ extra.connect
75
+ end
76
+
77
+ it 'should get the area from the screen' do
78
+ extra_screen.should_receive(:SelectAll).and_return(extra_area)
79
+ extra.connect
80
+ end
81
+
82
+ it 'should disconnect from a session' do
83
+ extra_system.should_receive(:Quit)
84
+ extra.connect
85
+ extra.disconnect
86
+ end
87
+ end
88
+
89
+ describe "interacting with text fields" do
90
+ it 'should get the value from the screen' do
91
+ extra_screen.should_receive(:GetString).with(1, 2, 10).and_return('blah')
92
+ extra.connect
93
+ extra.get_string(1, 2, 10).should == 'blah'
94
+ end
95
+
96
+ it 'should put the value on the screen' do
97
+ wait_collection = double('wait')
98
+ extra_screen.should_receive(:PutString).with('blah', 1, 2)
99
+ extra_screen.should_receive(:WaitHostQuiet).and_return(wait_collection)
100
+ wait_collection.should_receive(:Wait).with(1000)
101
+ extra.connect
102
+ extra.put_string('blah', 1, 2)
103
+ end
104
+ end
105
+
106
+ describe "interacting with the screen" do
107
+ it 'should know how to send function keys' do
108
+ wait_collection = double('wait')
109
+ extra_screen.should_receive(:SendKeys).with('<Clear>')
110
+ extra_screen.should_receive(:WaitHostQuiet).and_return(wait_collection)
111
+ wait_collection.should_receive(:Wait).with(1000)
112
+ extra.connect
113
+ extra.send_keys(TE3270.Clear)
114
+ end
115
+
116
+ it 'should wait for a string to appear' do
117
+ wait_col = double('wait')
118
+ extra_screen.should_receive(:WaitForString).with('The String', 3, 10).and_return(wait_col)
119
+ extra_system.should_receive(:TimeoutValue).and_return(30000)
120
+ wait_col.should_receive(:Wait).with(30000)
121
+ extra.connect
122
+ extra.wait_for_string('The String', 3, 10)
123
+ end
124
+
125
+ it 'should wait for the host to be quiet' do
126
+ wait_col = double('wait')
127
+ extra_screen.should_receive(:WaitHostQuiet).and_return(wait_col)
128
+ wait_col.should_receive(:Wait).with(4000)
129
+ extra.connect
130
+ extra.wait_for_host(4)
131
+ end
132
+
133
+ it 'should wait until the cursor is at a position' do
134
+ wait_col = double('wait')
135
+ extra_screen.should_receive(:WaitForCursor).with(5, 8).and_return(wait_col)
136
+ extra_system.should_receive(:TimeoutValue).and_return(30000)
137
+ wait_col.should_receive(:Wait).with(30000)
138
+ extra.connect
139
+ extra.wait_until_cursor_at(5, 8)
140
+ end
141
+
142
+ it 'should take screenshots' do
143
+ take = double('Take')
144
+ extra_session.should_receive(:WindowHandle).and_return(123)
145
+ Win32::Screenshot::Take.should_receive(:of).with(:window, hwnd: 123).and_return(take)
146
+ take.should_receive(:write).with('screenshot.png')
147
+ extra.connect
148
+ extra.screenshot('screenshot.png')
149
+ end
150
+
151
+ it 'should make the window visible before taking a screenshot' do
152
+ take = double('Take')
153
+ extra_session.should_receive(:WindowHandle).and_return(123)
154
+ Win32::Screenshot::Take.should_receive(:of).with(:window, hwnd: 123).and_return(take)
155
+ take.should_receive(:write).with('screenshot.png')
156
+ extra_session.should_receive(:Visible=).once.with(true)
157
+ extra_session.should_receive(:Visible=).twice.with(false)
158
+ extra.connect do |emulator|
159
+ emulator.visible = false
160
+ end
161
+ extra.screenshot('screenshot.png')
162
+ end
163
+
164
+ it 'should delete the file for the screenshot if it already exists' do
165
+ File.should_receive(:exists?).and_return(true)
166
+ File.should_receive(:delete)
167
+ take = double('Take')
168
+ extra_session.should_receive(:WindowHandle).and_return(123)
169
+ Win32::Screenshot::Take.should_receive(:of).with(:window, hwnd: 123).and_return(take)
170
+ take.should_receive(:write).with('screenshot.png')
171
+ extra.connect
172
+ extra.screenshot('screenshot.png')
173
+ end
174
+
175
+ it "should get the screen text" do
176
+ extra_area.should_receive(:Value).and_return('blah')
177
+ extra.connect
178
+ expect(extra.text).to eql('blah')
179
+ end
180
+
181
+ end
182
+ end
@@ -0,0 +1,146 @@
1
+ require 'spec_helper'
2
+
3
+ describe TE3270::Emulators::Quick3270 do
4
+
5
+ let(:quick) { TE3270::Emulators::Quick3270.new }
6
+
7
+ before(:each) do
8
+ WIN32OLE.stub(:new).and_return quick_system
9
+ quick.instance_variable_set(:@session_file, 'the_host')
10
+ end
11
+
12
+ describe "global behaviors" do
13
+ it 'should start new terminal' do
14
+ WIN32OLE.should_receive(:new).and_return(quick_system)
15
+ quick.connect
16
+ end
17
+
18
+ it 'should establish a session' do
19
+ quick_system.should_receive(:ActiveSession).and_return(quick_session)
20
+ quick.connect
21
+ end
22
+
23
+ it 'should get the screen from the active session' do
24
+ quick_session.should_receive(:Screen).and_return(quick_screen)
25
+ quick.connect
26
+ end
27
+
28
+ it 'should take the Visible value from a block' do
29
+ quick_system.should_receive(:Visible=).with(false)
30
+ quick.connect do |platform|
31
+ platform.visible = false
32
+ end
33
+ end
34
+
35
+ it 'should take the session file from a block' do
36
+ quick.should_receive(:session_file=).with('blah.txt')
37
+ quick.connect do |platform|
38
+ platform.session_file = 'blah.txt'
39
+ end
40
+ end
41
+
42
+ it 'should display an error when the session file is not set' do
43
+ quick.instance_variable_set(:@session_file, nil)
44
+ expect { quick.connect }.to raise_error('The session file must be set in a block when calling connect with the Quick3270 emulator.')
45
+ end
46
+
47
+ it 'should open the connection using the sesion file' do
48
+ quick_session.should_receive(:Open).with('blah.txt')
49
+ quick.connect do |platform|
50
+ platform.session_file = 'blah.txt'
51
+ end
52
+ end
53
+
54
+ it 'should default to Visible being true when not provided' do
55
+ quick_system.should_receive(:Visible=).with(true)
56
+ quick.connect
57
+ end
58
+
59
+ it 'should make the connection via the session' do
60
+ quick_session.should_receive(:Connect)
61
+ quick.connect
62
+ end
63
+
64
+ it 'should check to make sure the connection is successful before continuing' do
65
+ quick_session.should_receive(:Connected).once.and_return(false)
66
+ quick_screen.should_receive(:WaitHostQuiet).once.with(1000)
67
+ quick_session.should_receive(:Connected).once.and_return(true)
68
+ quick.connect
69
+ end
70
+
71
+ it 'should disconnect from a session' do
72
+ application = double('application')
73
+ quick_session.should_receive(:Disconnect)
74
+ quick_system.should_receive(:Application).and_return(application)
75
+ application.should_receive(:Quit)
76
+ quick.connect
77
+ quick.disconnect
78
+ end
79
+ end
80
+
81
+ describe "interacting with text fields" do
82
+ it 'should get the value from the screen' do
83
+ quick_screen.should_receive(:GetString).with(1, 2, 7).and_return('blah')
84
+ quick.connect
85
+ quick.get_string(1, 2, 7).should == 'blah'
86
+ end
87
+
88
+ it 'should put a value on the screen' do
89
+ quick_screen.should_receive(:MoveTo).with(15, 56)
90
+ quick_screen.should_receive(:PutString).with('blah')
91
+ quick_screen.should_receive(:WaitHostQuiet).with(3000)
92
+ quick.connect
93
+ quick.put_string('blah', 15, 56)
94
+ end
95
+ end
96
+
97
+ describe "interacting with the screen" do
98
+ it 'should know how to send function keys' do
99
+ quick_screen.should_receive(:SendKeys).with('<Home>')
100
+ quick_screen.should_receive(:WaitHostQuiet).with(3000)
101
+ quick.connect
102
+ quick.send_keys(TE3270.Home)
103
+ end
104
+
105
+ it 'should wait for a string to appear' do
106
+ quick_screen.should_receive(:WaitForString).with('string', 3, 10)
107
+ quick.connect
108
+ quick.wait_for_string('string', 3, 10)
109
+ end
110
+
111
+ it 'should wait for the host to be quiet' do
112
+ quick_screen.should_receive(:WaitHostQuiet).with(6000)
113
+ quick.connect
114
+ quick.wait_for_host(6)
115
+ end
116
+
117
+ it 'should wait until the cursor is at a position' do
118
+ quick_screen.should_receive(:WaitForCursor).with(5, 8)
119
+ quick.connect
120
+ quick.wait_until_cursor_at(5,8)
121
+ end
122
+
123
+ it 'should take screenshots' do
124
+ #TOD
125
+ end
126
+
127
+ it 'should delete the file for the screenshot if it already exists' do
128
+ #TOD
129
+ end
130
+
131
+ it 'should make the window visible before taking a screenshot' do
132
+ #TOD
133
+
134
+ end
135
+
136
+ it 'should get the screen text' do
137
+ quick_screen.should_receive(:Rows).and_return(3)
138
+ quick_screen.should_receive(:Cols).and_return(10)
139
+ 3.times do |time|
140
+ quick_screen.should_receive(:GetString).with(time+1, 1, 10).and_return("row #{time}")
141
+ end
142
+ quick.connect
143
+ quick.text.should == 'row 0\nrow 1\nrow 2\n'
144
+ end
145
+ end
146
+ end