How to handle network lag when UI script is invoked on systems with different hardware configuration

Asked by bgbig

I have written sikuli scripts for automation of one of our manual testing on a windows server 2012 system (virtual machine).

I have added customised wait in my scripts at numerous steps ..like clicking a next button wait(5)..clicking a close button....wait(3....) etc.

However,in order to deploy these scripts on a different VM ,there's a possibility that scripts might fail on account of network lag or the system being slow ..in finding the next image pattern in the control flow of script.

Is there a way to handle this in sikuli .Can you please suggest a way to rely less on wait(),sleep() etc. , functions i n sikuli.

Thanks in advance.

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
Last query:
Last reply:
Revision history for this message
Eugene S (shragovich) said :
#1

Hi,

Theoretically, there are 2 types of waits that can be used for automation:
- Implicit
- Explicit

What you have just demonstrated - is an implicit waits. It waits for a certain amount of time when trying to find an if they are not immediately available. This approach is prone to errors, just like it happens in your case, when you will get a timeout before the pattern appeared in the screen. Setting a longer wait time is not always a good idea since it will slow down the whole script even if that's not needed.

What you should do - is to implement an explicit wait. That means that you have to wait for a condition rather than just wait for a predefined period if time. So try to find something on the screen that indicates the fact that your previous action was completed. For example, if you click a button and it takes you to another screen, wait for an element that appears on that screen. Keep in mind that you still have to set some kind of timeout to avoid waiting forever.

For example:

retries = 10

for i in range (retries):
    try:
        find(object)
        print "Object found!"
        break
    except:
        print "Object was NOT found, retrying..."
        time.sleep(1)

Such script will wait for "object" to appear on the screen for 10 OR LESS seconds.

Eugene

Revision history for this message
RaiMan (raimund-hocke) said :
#2

I want to add to Eugenes correct approach:

In situations, where after a click action, that should change the screen content, the time to complete this screen change is varying (due to network or other delays), the only way to make such a workflow time efficient AND robust, is to wait for some expected image, that should signal the completion of the screen change after the click or other actions. In some situations the wait for the absence of an image might be used as well (waitVanish()).

You might either use Eugene's approach packed in a function or use wait(image, timeout).

In both cases the challenge is to decide for a maximum value for the timeout, that is sufficient in most cases.

Waiting for an image to appear is much more flexible than time based waits, since no matter, how long you set the timeout, in the moment, the image appears, the script will continue. The maximum delay you have is the time for one search.

click(someTarget)
wait(someFollowUpImage, maxTimeout)

Revision history for this message
Eugene S (shragovich) said :
#3

@RaiMan

I was so concentrated on my own approach that I completely forgot to mention the "wait(image, timeout)" option that I use quite extensively myself.

The reason to take my initial approach (with try/except) is if something additional must be done after each retry. For example, one could add some logging to indicate on the screen how many attempts were already made and how many left.

Eugene

Revision history for this message
RaiMan (raimund-hocke) said :
#4

@ Eugene
of course I have realized your intention ;-)

BTW: for version 1.2 I plan more options for FindFailed reactions and some "learning" of needed waiting times, which might help to adapt to these situations.

Revision history for this message
bgbig (bgbig) said :
#5

Thanks Eugene and RaiMan for correct use of wait image option .

Even I use wait(image,timeout extensively) as suggested by RaiMan ,but in my use case there is a lot of screen change ,like in a configuration package wizard of the SCCM tool .. i need to perform something like this.

click(self.myImages.getImage("nextButton"))
            logger.debug('Finalising set up ')
            for i in range(2):
                type(Key.DOWN)
                wait(1)
            click(self.myImages.getImage("nextButton"))
            wait(1)
            click(self.myImages.getImage("nextButton"))
            wait(5)
            logger.info('Successfully created configuration package')
            click(self.myImages.getImage("closeButton"))

Note: pls ignore the indentation

Now, here I know the next screen is bound to appear after a correct set of data is fed every time ,but in cases where network delay is predominant ,even this simple flow tends to fail ,just because the nextButton findfailed appears.

So is it advisable to use wait(image, timeout) after every nextButton click ,that way i'll have too many images in my image repository to handle and the script will become more cumbersome.
What do you suggest ??

This is just one module ,i have around five different sikuli modules each of average 200 lines of script already

Revision history for this message
Best RaiMan (raimund-hocke) said :
#6

in the mentioned example, it seems, that the ref image you are waiting for is the nextButton.

so this should do it:
           click(wait(self.myImages.getImage("nextButton"), maxDelay))

Revision history for this message
bgbig (bgbig) said :
#7

I was not aware of this feature : clubbing of click() and wait() into one.

Will try and use this functionality

thanks , i think this should serve the purpose .