I would like to propose a module that will interface with x3270 software to allow for automated operation/testing of mainframe applications.
There are automated testing tools for the mainframe, but most of them are proprietary and interact with proprietary terminal emulators. This module aims to provide an interface with an open source mainframe terminal emulator X3270. The X3270 allows a user to manually enter commands directly or by passing a file with the list of action instructions. By using this module, someone familiar with Perl can write an automated script which can access data from a file or database to drive automated operation or testing. If you wish to learn more, please feel free to contact me. I used to run a website on Perl but have moved it to another site (http://perl.conceptbc.ca) but have stopped because I discovered a lot of people getting ideas from my articles and claiming it as their own. I have created a video for proof of concept of this module in this video: https://youtu.be/UVqYYGLYqr8 Attached is a skeleton of the module I used in the video. Thank you. ============================ Philip Yuson Mainframe Consultant Concept Solutions Corporation P: 250-881-0049
package t3270; my $self = {}; sub new { print "Initializing t3270 session\n"; my $class = shift; my $key; while (@_) { $key = shift; $self->{$key} = shift; print "t3270: Ndx: $key\t$self->{$key}\n"; } tconnect($self); screenSize($self); bless $self, $class; return $self; } sub tconnect { my $self = shift; $self->{session} = IO::Socket::INET->new( Proto => 'tcp', # protocol PeerAddr=> $self->{server}, # Address of server PeerPort=> $self->{port}, # port of server Reuse => 1, ) or die "$!"; print "Connected to " . $self->{server} . # Info message " on port: " . $self->{port} . "\n"; $self->{session}->autoflush(1); # Send immediately } sub getScreen { my $self = shift; my $sess = $self->{session}; sendAction($self, "ascii\n"); $self->{screen}; } sub sendAction { my ($self, $str) = @_; my $sess = $self->{session}; if ($str !~ m/\n$/) { $str .= "\n"; } print "SENDING: $str----\n"; # if $self->{debug}; print $sess $str; getResult($self); $self->{screen}; sleep(1); } sub sendStr { my ($self, $str) = @_; my $sess = $self->{session}; $str = 'string("' . $str . "\") enter()\n"; sendAction($self, $str); # print $sess $str; # getResult($self); @{$self->{screen}}; } sub getResult { my $self = shift; $self->{screen} = []; my $sess = $self->{session}; my $l; my $lines = 0; my ($ok, $status, $error) = (); while ((! $ok and ! $error) or ! $status ) { print "--- Getting Response\n" if $self->{debug}; $lines++; $l = <$sess>; # Receive echo from server if ($l =~ m/^ok[\n\r]*$/i) { print "OK: $l: $status\n" if $self->{debug}; $ok = $l; } elsif ($l =~ m/^error[\n\r]*$/i) { print "ERROR: $l: $status\n" if $self->{debug}; $error = $l; } elsif ($l =~ m/^u f u c\(localhost\) i +\d+ +(\d+) +(\d+) +(\d+) +(\d+)/i or $l =~ m/^l f p n n (\d) (\d+) (\d+) (\d+) /i or $l =~ m/^u f p c\(localhost\) i +\d+ +(\d+) +(\d+) +(\d+) +(\d+)/i) { $self->{rows} = $1; $self->{cols} = $2; $self->{currow} = $3; $self->{curcol} = $4; if ($self->{debug}) { print "Cursor location: $self->{currow}\t$self->{curcol}\n"; print "Screen size: $self->{rows}\t$self->{cols}\n"; } $status = $l; print "Status: $status" if $self->{debug}; } elsif ($l =~ m/^data: (.+)+$/gi) { print '-'x20 . "\n$1\n" if $self->{debug}; } else { print 'x'x10 . "Unknown response: $l\n"; return; } push @{$self->{screen}}, $l; } } sub screenSize { my $self = shift; my $scr = sendAction($self, "ascii\n"); } sub searchRow { my ($self, $row, $str) = @_; unless ($row) { $row = $my->{currow}; } sendAction("ascii($row, 80, 80)"); if ($self->{screen}->[$row] =~ m/$str/gi) { return $self->{screen}->[$row]; } else { return -1; } } sub searchStr { my ($self, $str) = @_; my @rows = (); my $line; sendAction($self, 'ascii'); foreach (@{$self->{screen} } ) { $line++; if (m/$str/gi) { push @rows, $line; } } \@rows; } 1