[eggPlant Functional] Useful SenseTalk Functions

Here are a set of random data generators (often useful when making new filler/bogus test data.) Included is a SSN, First and Last name, even ‘real’ looking company name generators. Each object uses the getProp for a derived composite value for each instance of the RandomPerson object. Named RandomPerson, once is created the instance no longer is ‘random’…

Here is one that I like and hope others have a use for, the ImageCountShouldBe handler. You pass it a count and an image name. Although not as often useful, a list of images may be passed as well. Originally just a simple five line segment of script I was using over and over, ideal for a pullout and factor to a handler:

MoveTo  RemoteScreenSize()  -- move mouse out of the way
get number of items in EveryImageLocation(imageName)
if it <> expectedCount then
 LogError "The number of matching images found for image element '" & \
   image & "' should have be '"& expectedCount & \
   "', yet we have found '" & it & "' in only instances."

Now bloated and somewhat more robust, we have the all new ImageCountShouldBe handler:

params  count, images...

if count is not a positive number and count is not empty then
 insert count before images
 set count to 1
end if

MoveTo  RemoteScreenSize()  -- get mouse out of the way, allowing max image find as possible.

repeat with each image of images
 get number of items in EveryImageLocation(image)
 if it <> count then
  LogError "The number of matching images found for image element '" & image & "' should have be '"& count & \
    "', yet we have found '" & it & "' in only instances."
 else if universal imageCountShouldBeLogged is not in ( empty, off, no, false ) then
  Log "The number of matching images found for image element '" & image & "' was "& count & " instances."
 end if
end repeat

Here is how you can use this new handler, simple and to the point.

set universal imageCountShouldBeLogged to true  -- how you want reporting.
ImageCountShouldBe 10, testing

I’m sitting here wondering how in the world all the visual data that I have to verify on an hourly basis is going to get done easily while maintainable. Coming to my rescue yet again is SenseTalk, and some Eggplant functionality. I check the generation of PDFs and layouts fairly regularly as part of 90% of my automation development efforts, across projects, so I must have powerful easy to use tools in my toolbox of goodies.

Being able to to quickly verify the content of a page or area of layout is important, particularly against a baseline of external data sources. This in turn allows quick relatively fast migration from regressed tests to new version of software, both the tests and the AUT.

Here is a quick script to allow the identification either by point or image of a view on a webpage or AUT’s window to be selected all, and verified for content against a local file in /path/to/your/test.suite/Data. I like to use the term expectedData so it is clear in reading what is going on… And because I don’t always remember the path to the local suite, why not use a handler which considers the target in resolving the path, and put that handler into your tool-belt of tool-belts, EggplantCommons.suite or your own library suites.

params  imageOrLocation, pathOrData, stripLeadingTrailing

if there is a file pathOrData then
 set data to file pathOrData
else
 set dir to (( target's long name )'s folder's folder & "Data/")
 set files to ( each item in ( the files in dir ) where each contains pathOrData )
 set pathOrData to item 1 of files
end if

if stripLeadingTrailing is empty or stripLeadingTrailing is not a boolean then set stripLeadingTrailing to false

WaitForClick imageOrLocation

get FoundImageLocation()
SelectAll  it
Copy  it
Click  it  -- unselect so future images may be found.

wait 1 second  -- give SUT time to move data to pboard.
get RemoteClipboard()

if there is a file pathOrData then \
  set pathOrData to file pathOrData
if not stripLeadingTrailing then \
  set ( it, pathOrData ) to ( words 1 to -1 of it, words 1 to -1 of pathOrData )

return  it is pathOrData

There is a fair amount going on in this handler, yet in summary an image or location is used to click at a spot on the AUT/SUT. The data path or data source is resolved and used for comparison. Leading and trailing white space (strict comparisons) are either opted in or out, by default out. A fixed 1 second wait time is exercised to try and help the SUT get all the data onto the pasteboard and post a change. If you see your not getting the changes you need, make sure to lengthen this time a bit. Be careful, this time adds up quickly in many iterations to wasted minutes and hours done haphazardly.

And finally the comparison truth is returned.

One fairly simple yet powerful mod to this script would be to include a rectangle in which to drag out a region and copy that to the clipboard. Might want to simply check to see if the first to parameters are either existing images, or if they are not points to try and find the images assuming the images are available in one of the helper suites of your work. This brings up some very powerful expanded behaviour to this hander, left to the astute reader and EP/ST scripter.

Here is a simple function, but oh so powerful.

Often in multi application environments I must to verify text generated in one application against the data presented in another. This poses some problems, mostly intra and inter-suite communications. Using the results of RunWithNewResults helps, as does scraping screens for data that an application creates (for instance when creating new items in a database). Making assumptions the data generated (item numbers for instance) are accurate [kinda dangerous, but we live on the edge at times], we can scrape that info from the GUI and pass it along to the next dependent script in the chain of scripts to run.

(** take one or two parameters, if two then drag and drop, if just one move
to and select all **)

params  topLeft, bottomRight

get ImageLocation(topLeft)

if paramCount() is 1 then
 Click  topLeft
 SelectAll
else if paramCount() is 2 then
 Drag  topLeft
 Drop  bottomRight
end if

RightClick  it
WaitForClick  copy
wait until not ImageFound(copy)

return  the RemoteClipboard

So, what is this about you say? Well, its a simple one or two parameter screen scraping tool. Taken a point, or a two point region, we click, select all or drag and drop. That highlighted area is then right clicked and copied to the pasteboard. Finally that remote data is sent back to the calling script with a ‘the remoteClipboard’.

Here you can pass a rectangle to the function RandomPointWithin, and get back as you may expect a point within that rectangle, any point. No, this is not magic at all… Its about taking the base of the rectangle, and randomizing a number from 0 to the width and another from 0 to the height, add those respectively to the x and y portions of the origin of the rectangle… Presto, magic chango, you have a random point in the rectangle.

params  aRect

set x to aRect.x + random ( 0, aRect.width )
set y to aRect.y + random ( 0, aRect.height )

return ( x, y )


to UnitTest  x

 if x is not a number then set x to 5
 
 repeat x times
  put RandomPointWithin((0, 0, 30, 10 )) & " | "
 end repeat
 
end UnitTest

And if you unit test this, as we may always try in good scripting practices…

RandomPointWithin.UnitTest(100)
(4,3) | (19,7) | (19,10) | (8,3) | (29,6) | (16,9) | (13,2) | (9,2) | (27,7) | (3,1) | (6,4) | (21,6) | (7,3) | (24,10) | (9,9) | (8,5) | (8,5) | (18,4) | (28,1) | (12,5) | (15,2) | (24,1) | (29,0) | (27,6) | (9,9) | (12,3) | (6,9) | (7,2) | (12,0) | (21,2) | (23,9) | (0,8) | (24,6) | (21,6) | (12,6) | (15,3) | (26,0) | (20,9) | (6,5) | (18,5) | (12,7) | (29,5) | (28,2) | (29,2) | (1,3) | (28,10) | (15,8) | (19,4) | (14,5) | (26,7) | (10,7) | (18,5) | (16,3) | (29,3) | (22,5) | (4,1) | (11,2) | (20,4) | (3,8) | (17,5) | (1,6) | (26,10) | (10,9) | (23,5) | (24,10) | (18,0) | (27,1) | (8,0) | (11,6) | (30,0) | (18,10) | (4,10) | (2,3) | (2,4) | (5,5) | (7,8) | (29,0) | (21,4) | (12,7) | (1,0) | (30,8) | (8,0) | (23,3) | (4,10) | (18,0) | (4,7) | (3,6) | (28,10) | (26,5) | (6,6) | (16,8) | (6,10) | (11,6) | (21,4) | (8,8) | (27,6) | (9,0) | (0,0) | (14,3) | (3,8) | 

Hope you enjoy, and find stuff like this useful.

While I’m developing full screen or partial verification scripts for clients, it not uncommon for there to be changes occurring from one second to the next between actions. These changes must be verified at that point in the presentation layer of the GUI against baseline standards (values or layout requirements) for the software as part of the acceptance process as well as the QA process immediately at hand.

So, here is the basis of a sophisticated screen scraping system based on region identification (visual apparent) and complete page scraping which takes all visual text as its target.

(** take one or two parameters, if two then drag and drop, if just one move
to and select all **)

params  topLeft, bottomRight

get ImageLocation(topLeft)

if paramCount() is 1 then
 Click  topLeft
 SelectAll
else if paramCount() is 2 then
 Drag  topLeft
 Drop  bottomRight
end if

RightClick  it
WaitForClick  copy
wait until not ImageFound(copy)

return  the RemoteClipboard

So, what is this all about you say? Well, it is the core of a simple scraping tool. Taken a point, or a two point region, click, select all or drag and drop. The highlited area can be right clicked and copied to the pasteboard, and returned to the calling Eggplant script with a ‘get the remoteClipboard’ command.

Next time around I’ll approach the notion of regions and how you can use naming conventions along with other meta data to help locate, identify and gather information from the remote system quickly and effectively making your day a nicer happening.

Here we have a simple handler to normalize the spacing of a string with single spaces between words. If you wanted, you could add simple the double space after a punctuation/end of sentence.

params  @data

repeat with each line in data by reference
	set it to words 1 to -1 of it
end repeat

split data by return
join data with space

set data to each word of data
join data by space

return data

Where in example we have some text to normalize, you can see it is all messed up. So we throw the power of word selection, split and joins, and presto it all works out well in the end.

set data to <<On July 2 the Congress voted for independence by approving the Lee Resolution, twelve delegations voting in favor while the New York delegation abstained. (New
York did not cast its vote for the Lee Resolution until July 9.)
The Declaration was reworked somewhat in general session of the Continental
Congress. Congress, meeting in Inde  endence Hall in Philadelphia, shed revising
Jefferson's dr statement on July 4, approved it, and sent it to a printer. At the
signing, Ben.amin Franklin is quoted as having replied to a comment by Hancock
that they must all hang together: "Yes, we must, indeed, all hang together, or most
assuredly we shall all hang separately,"[4] a play on words indicating that failure to
stay united and succeed would lead to being tried and executed, individually, for
treason.>>

NormalizeSpacing @data
put data

And we end up with this…

On July 2 the Congress voted for independence by approving the Lee Resolution, twelve delegations voting in favor while the New York delegation abstained. (New York did not cast its vote for the Lee Resolution until July 9.) The Declaration was reworked somewhat in general session of the Continental Congress. Congress, meeting in Inde endence Hall in Philadelphia, shed revising Jefferson's dr statement on July 4, approved it, and sent it to a printer. At the signing, Ben.amin Franklin is quoted as having replied to a comment by Hancock that they must all hang together: "Yes, we must, indeed, all hang together, or most assuredly we shall all hang separately," [4] a play on words indicating that failure to stay united and succeed would lead to being tried and executed, individually, for treason.

Here’s a couple of quick and dirty helpers, if you follow the EggDoc standards for comment (see EggDoc for details)…

getProp  summary
 return words 1 to -1 of second item delimited by "(**" \
   of second item delimited by "**)" of my script
end getProp

This second property is more detailed as should your EggDoc comments. It gives the parameters and their details as well.

getProp  usage
 return words 1 to -1 of second item delimited by "(**" \
   of first item delimited by "**)" of my script
end getProp

You can then sweep thru each object/script and the objects with a property of usage or summary that are not equal can be used to build a usage and summary table for your internal and external publication.

Here is an example of how to use the summary command for a Script called TempFileName, which returns a temp file in the file system with some powerful naming features included.

put TempFileName's summary

Enjoy!

1 Like

Is the FilesExistExamples.suite.zip still available for download? :slight_smile: Thanks!

No, sorry.