te3270 0.1-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/ChangeLog +2 -0
- data/Gemfile +11 -0
- data/Guardfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +86 -0
- data/Rakefile +6 -0
- data/lib/te3270/accessors.rb +30 -0
- data/lib/te3270/emulator_factory.rb +21 -0
- data/lib/te3270/emulators/extra.rb +197 -0
- data/lib/te3270/emulators/quick3270.rb +178 -0
- data/lib/te3270/function_keys.rb +78 -0
- data/lib/te3270/screen_factory.rb +49 -0
- data/lib/te3270/version.rb +4 -0
- data/lib/te3270.rb +166 -0
- data/spec/lib/te3270/accessors_spec.rb +50 -0
- data/spec/lib/te3270/emulators/extra_spec.rb +182 -0
- data/spec/lib/te3270/emulators/quick3270_spec.rb +166 -0
- data/spec/lib/te3270/screen_factory_spec.rb +32 -0
- data/spec/lib/te3270_spec.rb +98 -0
- data/spec/spec_helper.rb +61 -0
- data/te3270.gemspec +29 -0
- metadata +147 -0
@@ -0,0 +1,49 @@
|
|
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 = 'Cheezy'
|
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
|
+
def on(screen_class, &block)
|
42
|
+
raise '@emulator instance variable must be available to use the ScreenFactory methods' unless @emulator
|
43
|
+
@current_screen = screen_class.new @emulator
|
44
|
+
block.call @current_screen if block
|
45
|
+
@current_screen
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
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
|
+
screen_object.should respond_to :method_name
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should generate a method to set the value' do
|
27
|
+
screen_object.should 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
|
+
screen_object.should_not respond_to :read_only=
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should default to being editable when it is not specified' do
|
35
|
+
screen_object.should 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
|
+
screen_object.method_name.should == '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('image.png')
|
147
|
+
extra.connect
|
148
|
+
extra.screenshot('image.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('image.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('image.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('image.png')
|
171
|
+
extra.connect
|
172
|
+
extra.screenshot('image.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
|
+
extra.text.should == 'blah'
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
end
|
@@ -0,0 +1,166 @@
|
|
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
|
+
take = double('Take')
|
125
|
+
quick_system.should_receive(:WindowTitle).and_return('The Title')
|
126
|
+
Win32::Screenshot::Take.should_receive(:of).with(:window, title: 'The Title').and_return(take)
|
127
|
+
take.should_receive(:write).with('image.png')
|
128
|
+
quick.connect
|
129
|
+
quick.screenshot('image.png')
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should delete the file for the screenshot if it already exists' do
|
133
|
+
File.should_receive(:exists?).and_return(true)
|
134
|
+
File.should_receive(:delete)
|
135
|
+
take = double('Take')
|
136
|
+
quick_system.should_receive(:WindowTitle).and_return('The Title')
|
137
|
+
Win32::Screenshot::Take.should_receive(:of).with(:window, title: 'The Title').and_return(take)
|
138
|
+
take.should_receive(:write).with('image.png')
|
139
|
+
quick.connect
|
140
|
+
quick.screenshot('image.png')
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should make the window visible before taking a screenshot' do
|
144
|
+
take = double('Take')
|
145
|
+
quick_system.should_receive(:WindowTitle).and_return('The Title')
|
146
|
+
Win32::Screenshot::Take.should_receive(:of).with(:window, title: 'The Title').and_return(take)
|
147
|
+
take.should_receive(:write).with('image.png')
|
148
|
+
quick_system.should_receive(:Visible=).once.with(true)
|
149
|
+
quick_system.should_receive(:Visible=).twice.with(false)
|
150
|
+
quick.connect do |emulator|
|
151
|
+
emulator.visible = false
|
152
|
+
end
|
153
|
+
quick.screenshot('image.png')
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should get the screen text' do
|
157
|
+
quick_screen.should_receive(:Rows).and_return(3)
|
158
|
+
quick_screen.should_receive(:Cols).and_return(10)
|
159
|
+
3.times do |time|
|
160
|
+
quick_screen.should_receive(:GetString).with(time+1, 1, 10).and_return("row #{time}")
|
161
|
+
end
|
162
|
+
quick.connect
|
163
|
+
quick.text.should == 'row 0\nrow 1\nrow 2\n'
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ScreenFactoryScreen
|
4
|
+
include TE3270
|
5
|
+
end
|
6
|
+
|
7
|
+
class World
|
8
|
+
include TE3270::ScreenFactory
|
9
|
+
end
|
10
|
+
|
11
|
+
describe TE3270::ScreenFactory do
|
12
|
+
|
13
|
+
let(:world) { World.new }
|
14
|
+
|
15
|
+
it 'should create a new screen object' do
|
16
|
+
emulator = double('platform')
|
17
|
+
world.instance_variable_set('@emulator', emulator)
|
18
|
+
world.on(ScreenFactoryScreen).should be_instance_of ScreenFactoryScreen
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should create a new screen object and execute a block' do
|
22
|
+
emulator = double('platform')
|
23
|
+
world.instance_variable_set('@emulator', emulator)
|
24
|
+
world.on(ScreenFactoryScreen) do |page|
|
25
|
+
page.should be_instance_of ScreenFactoryScreen
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should raise an error when an @emulator instance variable does not exist' do
|
30
|
+
expect { world.on(ScreenFactoryScreen) }.to raise_error("@emulator instance variable must be available to use the ScreenFactory methods")
|
31
|
+
end
|
32
|
+
end
|