Tuesday, June 12, 2007

Telnet in SilkPerformer

I've alluded to it previously, but I am brow deep in a volume testing effort around our new international Warehouse and Manufacturing software. While the software has a nice web UI, the primary method most users will use to interface with this software is through hand held RF devices. That means 80% of our automated scripts are emulating RF devices.

These devices will typically use the telnet protocol to 'talk' to a service that renders the UI to the device, accepts input, etc.

Early on, like 2003/2004, we spoke to our automated testing vendor about the need to support the telnet protocol. Needless to say, they supported tcpip out of the box, but not necessarily telnet.

Never fear, we wrote a wrapper library, around those tcpip functions and were able to accomplish our goal. Unfortunately, the vendor then turned around and added telnet 'application protocol' support to the next version of their software and wanted to charge us an upgrade fee (not part of regular maintenance) to have access to it, which I don't have budget for.

Its a great addition to the product and they've done a lot to it to add support beyond what our simple wrapper did. However, if your needs are pretty straight forward (ours are) you might be able to continue to get by with the simple library.

What you lose is the ability to 'record' a telnet conversation, but hey, I've not seen a telnet based application yet that you couldn't easily write down the necessary steps for.

hConnection - an existing, open, connection
strData - data we are sending
strPrompt - used for debugging only; visual cue of whats currently 'on screen'
strTokenList - delimited list of tokens to search response data for. RaiseError if unable to find this value.
strTimer - the timer to use; this is for measurement reporting.

returns the actual token that was found in the response buffer, or "" if not found.

function TelnetSendEx (hConnection : number; strData : string; strPrompt : string; strTokenList : string; strTimer : string) : string

strToken : string;


Print(strPrompt + ": " + strData);


WebTcpipSend(hConnection, strData + WEB_CRLF);

// now receive data
strToken := TelnetReceiveEx(hConnection, strTokenList, ";");


TelnetSendEx := strToken;

end TelnetSendEx;

hConnection - an existing, open connection.
strTokenList - delimited list of values to search the response data for
strDelimiter - the delimiter; e.g. ';'

returns the actual token found in the response buffer. It will return the first token it finds.
function TelnetReceiveEx(hConnection : number; strTokenList : string; strDelimiter : string ) : string

strToken : string;
strData : string;
isFound : boolean;


isFound := false;

strTokenList := strTokenList + ";Error;ERROR;

//Print("Token List: " + strTokenList);
//Print("Delimiter: " + strDelimiter);

WebTcpipRecvUntilIdle(hConnection, strData);

strToken := Strtok(strTokenList, strDelimiter);

while ( strToken <> "" )

Print("Searching for token: " + strToken);

if ( StrSearch(strData, strToken, STR_SEARCH_FIRST) > 0 )

isFound := true;
Print("Found token: " + strToken);


strToken := Strtok(NULL, strDelimiter);

if ( isFound = false )
RaiseError(CUSTOM_MESSAGE, "Failed to find any tokens: " + strTokenList, SEVERITY_WARNING);

TelnetReceiveEx := strToken;

end TelnetReceiveEx;

Sample calling the TelnetSendEx function.

hConnection, // the open connection
strItem, // data we are sending
"Enter Item Number", // current UI prompt (mainly for debugging)
"Enter Lot", // response text to validate for
"INV_3.25 Enter Item Number" // measurement name; used for reporting time

Sample checking for a specific response from TelnetSendEx:

strBuffer := TelnetSendEx(
hConnection, // connection
strLot, // data we are sending
"Enter Lot", // ui prompt
"Y/N;Number of Cases", // delimited list of values to check for
"INV_3.25 Enter Lot Number" // measurement name

if (stricmp(strBuffer, "Y/N") = 0)

// "Y/N" token found


No comments:

Post a Comment