Display post #
# through # Help

Goto page 1, 2, 3, 4, 5  Next  :| |:
TestPlant : Eggplant Examples :
All times are GMT - 8 Hours
Useful SenseTalk Functions

#1: PostPosted: Tue Jan 30, 2007 2:57 pm
Useful SenseTalk Functions Author: Todd

Thought some folks would like an easy to use, quick and dirty way to get field contents on a remote system (System Under Test, or SUT). Stick this into your own Toolbelt.script and start using it today.

Code:
-- Set the contents of a field to a value.  The image hot spot
-- determines where the click occurs relative to the image
-- found location.
to setContentsOfField   fieldName, fieldValue

  try
    Click fieldName
    TypeCommand "A", "C"  -- copy the text contents
    TypeText fieldValue
  catch e
    LogError("Error Clicking Image", e)
  end try
 
end setContentsOfField


and here is the getter function for the above, setting the field contents.

Code:
-- Grab a field's contents, marked by the image name as the
-- first parameter the image hot spot determines where the
-- click occurs relative to the image found location.
to contentsOfField  fieldName

  try
    Click fieldName
    TypeCommand "A", "C"  -- copy the text contents
    return remoteClipboard(10)
  catch e
    LogError("Error Clicking Image", e)
  end try
 
end contentsOfField


Try grabbing images that uniquely identify a text field. These handlers will quickly allow you to valid field data. As a test of utility and speed, I created a new test suite, added these handlers, created another driver handler and validated 5 fields of data in a repeat loop. It took me about 2 minutes, and should a new Eggplanter about ~10 mins.


Last edited by Todd on Sat Mar 24, 2007 10:45 am; edited 17 times in total

#2: PostPosted: Tue Mar 20, 2007 12:36 am
Validating email addresses before using the sendmail command Author: Todd

Thanks for all the great suggestions and comments from all our Eggplant users. Keep the questions coming!

This one comes from a large Bay Area company with dozens of Eggplant seats and is creating a fairly large testing and validation group around Eggplant.

Transitioning from, but still using a fairly manual test policy where testers run Eggplant scripts by hand, enter an email address at the start of the script so any validation information and reports can be sent to the proper engineers upon successful/failure of script/suite completion. The idea of email validation was needed, to at least ensure someone was entering a valid email and then use it for the SenseTalk SendMail command.

This AskForValidEmail was born as a result:

Code:
params aPrompt, aTitle, anAddress, useLast, allowCancel

-- Remember the last value entered ...
if useLast is not a boolean then set useLast to true
-- ... and allow cancel by default
if allowCancel is not a boolean then set allowCancel to true

repeat forever
 
  ask aPrompt title aTitle with anAddress
 
  -- get our results stored for later use.
  set ( theResult, email ) to ( the result, it )
  if email is empty and theResult is "Cancel" \
    and allowCancel then exit repeat
 
  if emailIsValid(email) then exit repeat
  if useLast then set anAddress to email
 
end repeat

return email



and this AskForValidEmail.script in turns calls a simple email validation EmailIsValid.script which checks basic email address validation rules.


Code:
params  address

if address is empty then return false

split address by "@"
if the number of items in address <> 2 then return false
set ( name, domain ) to ( items 1 to 2 of address )

-- ensure no inter-word spaces and one word for each
if number of words in name <> 1 then return false
if number of words in domain <> 1 then return false

-- and no outer-word spaces
if words 1 to -1 of name <> name then return false
if words 1 to -1 of domain <> domain then return false

return  true



You'll see 5 parameters to the AskForValidEmail, however none are required. It is a good idea however to provide at least the first 2, the prompt and title of the ask window. The 3rd is an optional email address. The 4th parameter to the AskForValidEmail handler is the optional useLast, which by default if left out from the call, then defaults to true. This will allow the user to quickly make changes to their email address data. If you set it to false, then the user will be represented with the original calling email address in the ask panel. And finally, the optional 5th parameter is the allowCancel, which enables or disables the ability of the user to cancel out of the ask panel. By default, this is true.

Its not often we want a user 'trapped' in the use of an ask panel. However there are rare cases where this would be desirable and supported. Most likely, you will use this handler in the fashion shown.

Included is the EmailValidation.suite and its Demonstration.script demonstrating how simple these handlers work together. See how simple it is to do data validation with SenseTalk:

Code:
AskForValidEmail "Enter Email Address", \
  "Destination Email For Reports", \
  "errors@yourcompany.com"

set validEmailAddress to the result

put validEmailAddress


Last edited by Todd on Sun Jun 24, 2007 8:39 pm; edited 1 time in total


EmailValidation.suite.zip
 Description:
Download, unzip, drag EmailValidation.suite to Eggplant. Take a look at the README.script (contains this article/post), and run the Demonstrate.script.

Download
 Filename:  EmailValidation.suite.zip
 Filesize:  31.2 KB
 Downloaded:  1327 Time(s)

#3: PostPosted: Wed Mar 21, 2007 12:45 am
Converting to and from Unicode Author: Todd

Often is the case where due to the Internet being rather centric to Unicode, one has to send streams or text on a clipboard to a remote SUT in the form of Unicode. Requested by a number of large Eggplant installations drove me to finally abstract and document the ASCII->X and X->ASCII conversion scripts in this ConversionExamples.suite.

Nothing really fancy here this time around, except of the inclusion of Redstone's EggDoc comments. You may want to download EggDoc (search in forums for it), and use it to document these scripts. Just Run EggDoc where it is, promting you for the path to the suite you wan to document.

The scripts take ASCII and Hex/Unicode and convert it one way or another. Basic filter stuff, but very useful when you have to encode before sending via a socket or pasteboard where the destination application expects only Unicode.

Download the attatchment suite, and run the Demonstration.script, mess around in the Playground.script and see how basic Unit Level Testing can be handled with a generic approach using the UnitTest.script.


Last edited by Todd on Mon Jul 30, 2007 8:55 pm; edited 1 time in total


UnicodeExample.suite.zip
 Description:
Download, Unpack, Drag and drop the *.suite onto Eggplant. Read the disclaimer, run the demo, and mess around with the Playground. Install EggDoc too, and run against this EB enabled suite.

Download
 Filename:  UnicodeExample.suite.zip
 Filesize:  38.64 KB
 Downloaded:  1298 Time(s)

#4: PostPosted: Tue Apr 03, 2007 11:14 am
Strings to Lists and Vector Math Author: Todd

Interestingly, few people actually leverage the list assignment and vector/list math features of SenseTalk. However, doing point math can be as important as breathing in some cases and problems arise when doing math with what seems like points and lists, but are actually strings. One must convert a string to a real point/list (a list with two numeric values) first before doing vector math. Here is a problematic example, using the ask command which returns a string regardless of the validity of the values being points or lists:

Code:
ask "Enter pt1" with "1,1"
set pt1 to it
ask "Enter pt2" with "3,3"
set pt2 to it
put pt2 - pt1 --> 5270400, or some time in seconds


This is tricky because of what SenseTalk is doing for you in the background. SenseTalk for the most part considers things as typeless, optimizing objects when it can, and leaving objects as strings whenever possible to minimize speed costs when dealing with data. In the above case, two points that are also strings. Thus they are not lists, and will be first attempted to be converted by default to dates, which they are (yes, "1,1" is a date, and so is "G3", as well as "yesterday"). Don't believe me? Execute this selection of ST code...

Code:
put yesterday is a date
put tomorrow is a date
put "1,1" is a date
put "G3" is a date  --> all output true


To help avoid making this into a date conversion issue, and keeping it as a list issue, I won't go into why conversion to dates is done first. When performing list math, the 2..N coordinate data must always be converted to a list. In some cases, using (variable) notation works, but few and far between does it work reliably with explicit conversion needs. SenseTalk has its own ideas when in context of how certain things should take place.

So, come the forced conversion routine:

Code:
to StringToList  @vars ...
  repeat with each list item in vars by reference
     split it
  end repeat
  return  vars
end StringToList


This very small routine converts each item in the variable length list argument @vars to list values by using the split command. Defaulting to comma, this routine expects lists to be in the form of strings, like "1,2,3,4,5", etc.

Finally a working example of code is well compressed into just a few lines:

Code:
set ( pt1, pt2 ) to ( "1,1", "3,3" )
StringToList @pt1, @pt2
put pt2 - pt1


To show even more flexibility, the StringToList handler is a 'to handler', which not only changes values by reference, but also will return the changed values themselves. This gives you the flexibility to call the handler two ways, either in the 'on handler' fashion, or in the 'function handler' fashion. Above the former was used above while below the function method of call is used.

Code:
set ( pt1, pt2 ) to StringToList( "1,1", "3,3" )
put pt2 - pt1


Download and play around, included in the StringToListExample.suite below are all the code examples above including the broken out code of StringToList. This makes it a drag and drop away from use in your own suites/libraries.



StringToListExample.suite.zip
 Description:
Download and play around, there are working and non working examples, as well as code broken out into a script for easy drag and drop into your own library/project.

Download
 Filename:  StringToListExample.suite.zip
 Filesize:  32.51 KB
 Downloaded:  1307 Time(s)

#5: PostPosted: Thu May 10, 2007 8:12 pm
Using property lists for chunk usage stats Author: Todd

I wanted to do some char and word usage stats on some large volumes of text, and came up with this handler to help. It leverages property lists, and how to dynamically perform math on empty containers value slots of key/value pairs. The result is a dynamic runtime definition of a value defined by a key.

Code:
to CharUsageStats  string

  repeat with each char of string
    add 1 to r's (it)
  end repeat
 
  return r
 
end CharUsageStats


If you wanted to take it to the next level and do word usage, the modification to the handler would be one word change...

Code:
...
  repeat with each word of string
...


and obviously renaming the handler to WordUsageStats.

And finally, we could redefine the function to be a more generic solution. The code could be told to give back stats on char, words, lines and paragraph usage stats.

Code:
to ChunkStats  string, chunkType

  if chunkType is not in ( char, word, line, paragraph ) then
    set chunkType to char
  end if
 
  -- special case, itemize with split by return & return
  if chunkType is paragraph then
    set ( chunkType, delim ) to ( item, return & return )
    split string by delim
  end if
 
  -- Send modified code to SenseTalk compiler and runtime.
  do merge(<< repeat with each [[chunkType]] of string
    add 1 to r's (it)
  end repeat>>  )
 
  return r
 
end ChunkStats


and you can test the code with the following (assuming you get some text first into the global 'it' variable.

Code:
repeat with each item type in ( char, word, line, paragraph )
  put ChunkStats(it, type)
end repeat


Happy chunking.

#6: PostPosted: Tue May 22, 2007 3:12 pm
Dollars and Sense, talk that is... Author: Todd

One of our fav customers sent in an email, wanting to know how to format some numbers to comma delimited format. ie. 1234 to 1,234. I have taken liberty on what Doug sent back to our trusted fellow scripter, and expanded it to format to dollars and "sense". 1234.567 -> $1,234.57

Code:
to commaFormat number
  repeat with n = length of number - 3 down to 1 step 3
    put comma after char n of number
  end repeat
  return number as text
end commaFormat


the above handle goes backwards (right to left) in 3 char chunks inserting commas along the way. This works because the left of a number is going to be flexible and have either 3 or 2 or even 1 number to the left of the leftmost comma.

Code:
to dollarsAndCents number
  set the numberFormat to ".00"
  set cents to round(number - trunc(number), 2)
  return "$" & commaFormat(trunc(number)) & last 3 chars of cents
end dollarsAndCents


Then the dollarsAndCents conversion works simply by taking the difference of the commaFormat() function above, and appends the rounded to 2 decimal places cents value and returning it all as the result.

Code:
set val = "6003905587.190000000"
put dollarsAndCents(val)


The "val"ue is set to a large arbitrary number. The call to DollarsAndCents with val as the parameter. We then convert back to the original number. Since we lost the rounded portion, that is not possible to recover, the best we can do is get back the unformatted dollars and cents value.

Code:
to dollarsToNumber  number
  delete all "$" from number
  delete all "," from number
  return number
end dollarsToNumber


And finally we get to test the code...

Code:
repeat 20 times
  get dollarsAndCents(randomValue(3,4))
  write it && "<->" && dollarsToNumber(it) & return
end repeat


Along with some random data:

Code:
to randomValue  x, y
  if x is empty then set x to 5
  if y is empty then set y to 2
  return random(10^x) & "." & random(10^y)
end randomValue


Thanks for Doug Simons for the quick reply and trick for doing the comma insertion, going backwards in the string as well as fuel for the ideas to convert to real dollar format as well as back.

#7: PostPosted: Fri Jun 01, 2007 12:46 pm
RE: files exist functions. Author: Todd

At times there is a need at the start of a suite run to check and see if series of files exists. Maybe they are data files, maybe they are image files, maybe they are configuration files. Here you will find a set of functions offering flexibility in checking to see if a single or list of files exists, or is absent. You may want to write your own 'whichFilesAreMissing()' function as well.


FilesExistExamples.suite.zip
 Description:

Download
 Filename:  FilesExistExamples.suite.zip
 Filesize:  28.68 KB
 Downloaded:  1264 Time(s)

#8: PostPosted: Fri Jun 01, 2007 1:28 pm
Image Locations, left, right, above, below and quadrant Author: Todd

Here are a quick collection of functions that allow you to determine if one image is located to the right, left, above, below, and combinations there of from each other.

Last edited by Todd on Sun Jun 24, 2007 8:27 pm; edited 1 time in total


ImageOrientationExample.suite.zip
 Description:
Download, unzip. The images are not likely to be on your screen, so explore and capture your own SUT images. Then play with the Main.script to see how it works.

Download
 Filename:  ImageOrientationExample.suite.zip
 Filesize:  117.65 KB
 Downloaded:  1332 Time(s)

#9: PostPosted: Tue Jun 05, 2007 6:47 am
Deleting all cookies in Safari (start state) and TIG Author: Todd

Often someone has to establish a known start state, or in this case eliminate the existing cookies in an browser so that old user names or passwords are not autofilled when testing a login page during script execution.

Deciding to take the TIG approach, to dynamically create the images on the fly with just the text to search, the following script was generated in about the same time as the image grab would have taken.

Code:
-- Small script'ette to delete all the cookies in safari
Click  (Text: "Safari", TextStyle: ApplicationMenu )
Click  ( Text: "Preferences", TextStyle: Menu ) -- or TypeCommand ","
Click ( Text: "Security", TextFont: "LucidaGrande", \
  TextSize: 11 )
Click ( Text: "Show Cookies", TextFont: "LucidaGrande", \
  TextSize: 13 )
get ( Text: "Remove All", TextFont: "LucidaGrande", \
  TextSize: 13, Tolerance: 80 )
if ImageFound(30, it) then
  Click FoundImageLocation()
  WaitFor 30, ( Text: "Remove All", TextFont: "LucidaGrande", \
    TextSize: 13, TextBackgroundColor:(120,167,237))
  Click FoundImageLocation()
end if
Click ( Text: "Done", TextFont: "LucidaGrande", \
  TextSize: 13, TextBackgroundColor:(120,167,237))
TypeCommand "w"


Since this is a OS X type posting, where these things will work only on OS X, here is how you could open an application installed in the standard /Applications directory (in this case, Safari):

Code:
TypeText  commandDown, shiftDown, "g", shiftUp, commandUp
TypeText "/Applications"  -- the default path to applications on OS X
TypeText return  -- makes Finder open a window to previous typed path
TypeText "Safari"  -- selects the app
TypeCommand "o"  -- opens up the app


and finally, to answer how someone could easily get the login and password into the field, you could use the following:

Code:
Click ( Text: "label", TextStyle: aStyle, HotSpot: offset )
TypeCommand "a"  -- select all
TypeCommand "x"  -- delete all, or could have used  TypeText  backspace
TypeText "newlogin"  -- your new login
TypeText tab  -- tab to the password field
TypeText "newpassword"  -- your new password
TypeText return

#10: PostPosted: Tue Jun 19, 2007 8:34 am
Time Elapsed Function Author: Todd

From one of our Middle East clients, the issue of elapsed time format came into play today. Wanting to know how to format a script's duration time into HH:MM:SS with SenseTalk's FormattedTime() function, I was perplexed by the results. Asking the SenseTalk creator, Doug Simons on how to handle various results that looked to be based on GMT, the sticky and complex issue of time zones came into play. Our Israeli friend had asked how to take X seconds and format into HH:MM:SS and was using

Code:
put FormattedTime("%H:%M:%S", the result's duration seconds)


However this returned 2:00:02, if the scripts took 2 seconds to run to completion. In my case, in the CMT zone, the result was 18:00:02. Ok, so why? Immediately I thought time zone to GMT. To find out how many hours from GMT you are, try

Code:
put the secondsFromGMT / 1 hour


which in my case will output -5, or 5 hours behind the Greenwich Mean Time. I'm currently in daylight savings. Seconds are calculated using January 1st, 2001 as the epoch, and January doesn't have daylight savings. It was standard time during that period of the year. We have to resort to using something more current as reference, maybe today would work. Thus the following proved usable to figure out elapsed time and have it formatted in actual localized time, not GMT referenced time.

Code:
params   aTime
return formattedTime("%H:%M:%S", today - 12 hours + aTime)


We take today, subtract 12 hours (cause today is at noon in SenseTalk), and add aTime to it, thus giving us an elapsed time that is in absolute time. Now put this into a newly minted handler named FormatElapsedTime and can get 'zone adjusted' elapsed time any time you want.

Code:
put FormatElapsedTime(3599 seconds)  --> 00:59:59


We hope this has helped clear up some time/date issues which may have arisen when considering, formatting and calculating times.


Page 1 of 5


Goto page 1, 2, 3, 4, 5  Next  :| |:


Output generated using Printer-Friendly Topic Mod.


Powered by phpBB © 2001, 2005 phpBB Group