i am trying to override some eggplants commands so that they provide a better error handling for my testing.
I have, within my suite a script call myUtil wich i “start using” before any script i create.
most of the things work fine, but i am having an issue with this particular piece of code:
to Click myImage, myError, myDesc
If myError is empty then put "UNEXPECTED" into myError
If myDesc is empty then put "Unable to find image: "&myImage into myDesc
try
If ImageFound(myImage) then
send Click FoundImageLocation() to SenseTalk
end if
catch anException
throw myError, myDesc
end try
end Click
when i try to do Click “SomeImage” from a script, i get this result:
So i was right, the try was “testing” the success of the if command.
i changed the code a bit, and now works as intended… i am posting it here, but if any of you have suggestions for improving this i will appreciate it because i feel is not too elegant.
to Click myImage, myError, myDesc
If myError is empty then put "UNEXPECTED" into myError
If myDesc is empty then put "Unable to find image: "&myImage into myDesc
try
ImageFound(myImage)
catch anException
throw myError, myDesc
end try
send Click FoundImageLocation() to SenseTalk
end Click
So you are very close but are missing a key point:
The imageFound() function returns a bool value as to if the image is found on screen or not; but it won’t throw an exception if the image isn’t found. This was the problem in your first syntax. Mostly imageFound() won’t ever throw an exception, except when used as a statement like your second case where it will ALWAYS raise an exception.
I think what you really want is to just try the click and if THAT throws an exception you want to do your own error.
to Click myImage, myError, myDesc
If myError is empty then put "UNEXPECTED" into myError
If myDesc is empty then put "Unable to find image: "&myImage into myDesc
try
send Click myImage to SenseTalk
catch anException
throw myError, myDesc
end try
end Click
You are absolutely right, i didn’t notice that before, although your code is right on the spot is missing something i want, which is ensure the image is there before clicking it.
Any suggestions? i am trying to avoid the
waitFor Time, Image
click FoundImageLocation()
idiom.
( less lines of codes in the test )
[EDIT: Maybe ensure is too strong of a wording, to avoid timing issues without sprinkling waits in the test code, i want to wait for the image before clicking it ]
The first issue is what do you want your handler to do if the image is NOT on screen. Do you want it to throw an error or just warn and continue?
The code above will throw an error (just like the click command).
As far as waiting is concerned. The click command already has a certain amount of waiting that it will do all the time (the imageSearchTime). If you want to specify a longer (or shorter) minimum search time you can pass an optional time argument as it’s first value.
Click 20, “MyImage” – short for search for MyImage for 20 seconds and click it.
Thank you very much, didn’t know that. how about this
to Click howLong, myImage, myError, myDesc
If howLong is empty then put 1.0 into howLong
If myError is empty then put "UNEXPECTED" into myError
If myDesc is empty then put "Unable to find image: "&myImage into myDesc
try
send Click howLong, myImage to SenseTalk
catch anException
throw myError, myDesc
end try
end Click
Just found an error in my previous solution, if i provide image, error and desc but not a time ( Click “Image”, “ERROR”, “Reason” ) the positional arguments will think “Image” is the time to wait… :S Help!
if howLong is empty then
click myImage
else
click howLong, myImage
As an aside, I would make the howLong argument the 4th argument and then you can more easily include or exclude it (if you plan to only specify it some of the time.
Is there any way to specify it as the first argument while at the same time making it optional? something like verifying the first parameter is a number or a string?
Making anything other than the last argument(s) optional is bad coding practice. But if you want to leave a parameter out, just use a comma:
doSomething , , "dog", "cat"
to dosomething
put param(1) -- outputs nothing
put param(2) -- outputs nothing
put param(3) -- outputs "dog"
put param(4) -- outputs "cat"
end doSomething
I dont mean to second guess your advice, regarding bad coding practice, but why exactly is it bad to have the first parameter be optional? i was just trying to replicate the functionality of ImageFound(“Image”) that has an optional parameter for timing ImageFound(Time,“Image”)
While the time parameter may be described as optional parameter, it’s really not optional. What happens is the first parameter is checked to see if it is a number and if it is, then it is used as a timeout value. When you don’t specify a time, it’s not as though the function treats it like there’s an empty value in the first position, it just uses the first parameter as an image name. Some people might argue that that’s not great programming practice either, but it’s a little cleaner than truly having an optional first parameter.
To look at it another way, you’re not required to do anything to indicate that you’re not specifying a time parameter; if it were truly an optional parameter, you’d need to somehow provide an empty value to indicate that you knew it was there and you were intentionally leaving it out. That’s why it’s better to have truly optional parameters at the end of the list of arguments – the user doesn’t need to do anything special to leave them out.
In some languages the function with the time parameter and the one without would be two different functions and the compiler would use the correct one based on the “signature” of the function. The call with a number in the first position would be distinct from the call with an image (string) in the first position. We don’t have that ability, largely, I believe, because SenseTalk is not strongly typed.
(* Overrides default click--Clicks a an image until the target display opens. This is necessary because certain display clicks do not always register, regardless of whether the click is via automation or not *)
//imageToClick: [any image]
//imageToSearchFor: [usually a display identifier--any image that you would expect to find after the click is successful
to Click imageToClick, imageToSearchFor
if imageToClick is a number or imageToClick is a point or imageToSearchFor is empty then
//Timeout value, coordinates, or no imageToSearchFor indicate normal clicking is desired
send Click parameterList() as parameters to SenseTalk
else //Click until expected image is found, or operation fails too many times
if ImageFound(imageToClick) then
repeat while not ImageFound(imageToSearchFor)
send Click FoundImageLocation() to SenseTalk
if repeatIndex() is greater than 10 then
LogError "Could not open" && display_id && "display. Please correct script. See screenshot for moree information"
end if
end repeat
else
LogError imageToClick && "could not be found on the screen. See screenshot and correct script."
end if
end if
end Click
[quote=“craigmachaffie”]just wanted to share my click override as well:
(* Overrides default click--Clicks a an image until the target display opens. This is necessary because certain display clicks do not always register, regardless of whether the click is via automation or not *)
//imageToClick: [any image]
//imageToSearchFor: [usually a display identifier--any image that you would expect to find after the click is successful
to Click imageToClick, imageToSearchFor
if imageToClick is a number or imageToClick is a point or imageToSearchFor is empty then
//Timeout value, coordinates, or no imageToSearchFor indicate normal clicking is desired
send Click parameterList() as parameters to SenseTalk
else //Click until expected image is found, or operation fails too many times
if ImageFound(imageToClick) then
repeat while not ImageFound(imageToSearchFor)
send Click FoundImageLocation() to SenseTalk
if repeatIndex() is greater than 10 then
LogError "Could not open" && display_id && "display. Please correct script. See screenshot for moree information"
end if
end repeat
else
LogError imageToClick && "could not be found on the screen. See screenshot and correct script."
end if
end if
end Click