Introduction
I am writing this tip not to recommend Eggplant but to show how did I managed to make it usable and useful.
Background
We were searching for an automation tool that is platform independent and has page rendering capability, and can be used for mobile automation and for Web/Desktop apps as well. Because Eggplant is based on working with images it is suitable for any devices that has VNC server installed.
I am not aware about the new enhancements that are coming with new versions of Eggplant this is why it worth to mention that the version I have used was: 12
In this article I am going to share the solutions I have found previously and which helped me improve the stability of the automated scripts.
Before going further with examples please note: the development language used by Eggplant is SenseTalk.
Try catch in SenseTalk
Pretty similar to other languages:
try
<critical peace of code here>
catch e
LogError("some text here", e)
end try
Global variables
If you intend to use global variables you will need to use the global statement while declaring and using those variables:
put 1 into global startIndex
log "Start index:" & global startIndex
put 15 + global startIndex into global endIndex
log "End index:" & log global endIndex
the result of the above script is:
Start index:1
End index:16
Wait for object(image) capabilities
Because eggplant testing is based on images I have made several functions for waiting images to appear on the screen before trying to make any actions on them:
This function waits for an object to appear on screen
function WaitUntilObjectExist(myObject, timeout)
try
wait 1
log myObject
(*log timeout*)
repeat timeout times
if ImageFound(2, myObject) then
return 1
end if
end repeat
catch e
LogError("In Function WaitUntilObjectExist, " +
"error occured while searching for object["&myObject&"]", e)
end try
return 0
end WaitUntilObjectExist
This function waits until an object exists at the same location with anchor one
function WaitUntilObjectAtTheSameLocationExist (anchor,targeting,
intLeftBound, intTopBound, intRightBound,intBottomBound, timeout)
wait 1
put ImageRectangle(anchor) into bounds
set the SearchRectangle to ((bounds.left + intLeftBound,
bounds.top + intTopBound), (bounds.right +
intRightBound, bounds.bottom + intBottomBound))
put 0 into found
try
repeat timeout times
wait 1
if ImageFound(2, targeting) then
put 1 into found
exit repeat
end if
end repeat
catch e
end try
(*reset the search rectangle to the full viewer window(default location)*)
set the SearchRectangle to ()
return found
end WaitUntilObjectAtTheSameLocationExist
This function will wait for the object to appear and will call PageDown
event if not it will also click on the image in case it is found
on PageDownUntillObjectExist(targeting, timeout)
try
repeat timeout times
wait 2
if ImageFound(2, targeting) then
exit repeat
end if
pressPageDown
end repeat
catch e
LogError "Error while trying to page down while searching for ["&targeting&"]", e
end try
end PageDownUntillObjectExist
I will show the code for pressPageDown
later in this article.
Finding Images
This function is returning the targeting object which is on the same line as the anchor object
function returnImageAtTheSameLocation (anchor,
targeting, intLeftBound, intTopBound, intRightBound,intBottomBound)
put ImageRectangle(anchor) into bounds
put ((bounds.left + intLeftBound, bounds.top + intTopBound),
(bounds.right + intRightBound, bounds.bottom +
intBottomBound)) into targeting.searchRectangle
put ImageFound(targeting) into evaluate
return targeting
end returnImageAtTheSameLocation
This function is returning an image location related to an anchor
function returnImageLocationAtTheSameLocation (anchor,
targeting,intLeftBound, intTopBound, intRightBound,intBottomBound)
put WaitUntilObjectExist(anchor, 2) into evaluate
put ImageRectangle(anchor) into bounds
set the SearchRectangle to ((bounds.left + intLeftBound, bounds.top +
intTopBound), (bounds.right + intRightBound, bounds.bottom + intBottomBound))
if ImageFound(targeting)
put ImageLocation(targeting) into location
else
put (0,0) into location
end if
set the SearchRectangle to ()
return location
end returnImageLocationAtTheSameLocation
Read Text
This function returns the text related to an anchor image
function returnTextAtTheSameLocation (anchor,intLeftBound, intTopBound, intRightBound,intBottomBound)
put WaitUntilObjectExist(anchor, 2) into evaluate
put ImageRectangle(anchor) into bounds
put "" into valueReaded
put ReadText ((bounds.left + intLeftBound, bounds.top +intTopBound),
(bounds.right + intRightBound, bounds.bottom + intBottomBound), (trim: true)) into valueReaded
return valueReaded
end returnTextAtTheSameLocation
Press Key
Here are few examples of pressing keys in SenseTalk
On pressEnter
TypeText EnterKey
End PressEnter
On pressPageDown
TypeText PageDown
End pressPageDown
On pressControl_T
TypeText ControlKey, "t"
End pressControl_T
On pressControl_C
TypeText ControlKey, "c"
End pressControl_C
On pressControl_V
TypeText ControlKey, "v"
End pressControl_V
On pressTab
TypeText TabKey
End pressTab
On pressWindows_R
TypeText WindowsDown, "r" ,WindowsUp
End pressWindows_R
Reading property files
Supposing our property file contains the following lines:
testKey1,testValue1
testKey2,testValue1
testKey3,testValue1
Here is the function that reads the file
function readPropertyFile(datafile)
if there is a file datafile then
log "file ["&datafile&"] exists"
end if
repeat with each line of file datafile
put item 2 of it into propertiesList.(word 1 of item 1 of it)
end repeat
return propertiesList
end readPropertyFile
Writing property files
On WriteDataIntoFile(str, fileName)
if there is a file fileName then
open file fileName for appending
write str & return to file fileName
Close file fileName
else
open file fileName
write str & return to file fileName
Close file fileName
end if
end WriteDataIntoFile
Creating and using frameworks
Here are some tricks on how can frameworks be developed in eggplant: (I am not sure if there is another way to do this however this is the workaround I have found)
- Create a suite named Framework.
- Create a new (
Framework.script
) script and put some functions in it. - Create a second suite and start a new script.
- To load the functions from the
Framework.Script
into the second suite use the following example:
put "..\FrameworkSuite.suite\Scripts\Framework" into Framework
make sure the relative path is correct.
- You can now use the functions from the framework:
put Framework.WaitUntilObjectExist("Enter password", 15) into evaluate
or
run Framework.PageDownUntillObjectExist("Login", imgLoginInput, 10)
We use:
put when the method is created using function statement.
run when the method is created using on statement
Keep evidence of found defects
Each automated script should have a method to prove that the found defect is a valid one. So does Eggplant. It has the ability to capture screenshots.
In my case I am capturing a screen image whenever an error occurred while running a script.
Here is the function for logging errors:
on logErrorExit(errorString, e)
(*Write error details into the log*)
WriteDataIntoFile "Error and exit:" & errorString, global errorLogFile
(*Capture and save the screenshot*)
CaptureScreen (Name:errorLogFile &
".errorImage" & global errorIndex, increment:yes)
(* increment the index of the image found*)
put global errorIndex + 1 into global errorIndex
log "Error:" & errorString, e
(*Exit execution*)
exit all
end logErrorExit
Points of Interest
Intended for those who plant to use eggplant for automation.